diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..de0545d5257256b6dbde07ba286dd3c145170f93
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry including="**/*.java" kind="src" output="target/classes" path="src">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.fx.ide.jdt.core.JAVAFX_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="lib/matheclipse-core-1.0.0-SNAPSHOT-jar-with-dependencies.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream-1.4.11.1.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/activation-1.1.1.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/cglib-nodep-2.2.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/dom4j-1.6.1.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/jdom-1.1.3.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/jdom2-2.0.5.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/jettison-1.2.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/joda-time-1.6.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/kxml2-min-2.3.0.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/stax-1.2.0.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/stax-api-1.0.1.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/wstx-asl-3.2.7.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/xmlpull-1.1.3.1.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/xom-1.1.jar"/>
+	<classpathentry kind="lib" path="lib/xstream/xstream/xpp3_min-1.1.4c.jar"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/.project b/.project
new file mode 100644
index 0000000000000000000000000000000000000000..fae6075216d798dc7255eb82a27b4eadc3e98e58
--- /dev/null
+++ b/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Infographer</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..91ca62e2761b9b632ad25bfa2bc6e543c97e4f0d
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,14 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.ltk.core.refactoring.prefs b/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..f897a7f1cb2389f85fe6381425d29f0a9866fb65
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/gallery/Outbreaks-impact.json b/gallery/Outbreaks-impact.json
new file mode 100644
index 0000000000000000000000000000000000000000..1de3bc0f176039b8176715408d176943f16d208c
--- /dev/null
+++ b/gallery/Outbreaks-impact.json
@@ -0,0 +1,317 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":65.0,
+        "y":1205.0,
+        "sticky-y":"No",
+        "sticky-x":"Yes",
+        "distribution-x":"Distance",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":116.0625,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+        "variable":["A.x","x","height"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":20.0,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":29.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":-33.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x334db3ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":29.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":57.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xb3ccffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":58.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":80.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":136.0625,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":29.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":-26.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x334db3ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":29.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":43.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xb3ccffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":58.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":96.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":252.125,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":29.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":-29.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x334db3ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":29.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":41.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xb3ccffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":58.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":58.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":368.1875,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":29.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":-23.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x334db3ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":29.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":64.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xb3ccffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":58.0,
+                    "y":1.0,
+                    "width":29.0,
+                    "height":115.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/Outbreaks-impact.wrk b/gallery/Outbreaks-impact.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..65f4ad2e1cd5bafcdfdfd172bd9aba21f7e09065
--- /dev/null
+++ b/gallery/Outbreaks-impact.wrk
@@ -0,0 +1,1954 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":96.875,
+            "y":785.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":90.0,
+            "y":871.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+            "variable":["x","y","width","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":125.0,
+                        "y":141.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":88.0,
+                        "y":76.0,
+                        "width":18.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":116.0,
+                        "y":36.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":206.0,
+                        "y":69.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":186.0,
+                        "y":114.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":266.0,
+                        "y":107.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":216.0,
+                        "y":141.0,
+                        "width":14.0,
+                        "height":14.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":300.0,
+                        "y":188.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":30.0,
+                        "y":56.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":67.0,
+                        "y":104.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":126.0,
+                        "y":68.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":164.0,
+                        "y":71.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":147.0,
+                        "y":116.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":257.0,
+                        "y":157.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":311.0,
+                        "y":149.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":237.0,
+                        "y":97.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":143.75,
+            "y":808.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Distance",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":44.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.y","x","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":44.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":88.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":132.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":176.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":122.0,
+            "y":908.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":29.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+            "variable":["x","height","fill"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":15.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":85.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xccccccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":44.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":129.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x808080ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":73.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":42.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e64dff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":102.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":68.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x80b380ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":494.0,
+            "y":913.0,
+            "sticky-y":"Yes",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["y","width"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2","reference-x3"],
+                ["reference-y1"],
+                ["reference-y2","reference-y3"],
+                ["x1","x2","x3"],
+                ["height1","height3"],
+                ["height2"],
+                ["shape1","shape2","shape3"],
+                ["fill1","fill3"],
+                ["fill2"],
+                ["stroke1","stroke2","stroke3"],
+                ["thickness1","thickness2","thickness3"],
+                ["rotation1","rotation2","rotation3"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Top",
+                  "x":0.0,
+                  "y":-41.0,
+                  "width":92.0,
+                  "height":10.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e699ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":2.0,
+                  "width":13.0,
+                  "height":86.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffe6ccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":50.0,
+                  "width":55.0,
+                  "height":10.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e699ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0x808080ff",
+            "x":136.0,
+            "y":972.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["x","y","height"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":20.0,
+                  "y":133.0,
+                  "width":25.0,
+                  "height":162.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":106.0,
+                  "y":80.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":193.0,
+                  "y":206.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":281.0,
+                  "y":135.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":277.0,
+                  "y":34.0,
+                  "width":25.0,
+                  "height":49.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ],
+            "fill":"0xcce6ffff",
+            "opacity":0.3015873015873016,
+            "coloring":"Source",
+            "connections":[
+                {
+                  "origin":"2",
+                  "destination":"5",
+                  "weight":49.0
+                },
+                {
+                  "origin":"3",
+                  "destination":"4",
+                  "weight":81.0
+                },
+                {
+                  "origin":"1",
+                  "destination":"2",
+                  "weight":81.0
+                },
+                {
+                  "origin":"1",
+                  "destination":"3",
+                  "weight":81.0
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":65.0,
+            "y":1205.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":116.0625,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","x","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":20.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":29.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":-33.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x334db3ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":29.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xb3ccffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":58.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":80.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":136.0625,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":29.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":-26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x334db3ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":29.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":43.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xb3ccffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":58.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":96.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":252.125,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":29.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":-29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x334db3ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":29.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":41.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xb3ccffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":58.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":58.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":368.1875,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":29.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":-23.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x334db3ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":29.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":64.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xb3ccffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":58.0,
+                        "y":1.0,
+                        "width":29.0,
+                        "height":115.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Table",
+            "row":7,
+            "column":0,
+            "nrows":12,
+            "ncolumns":6,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["A.id","id","A.x","x","height","fill"],
+            "variables":[
+                {
+                  "name":"A.id",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Outbreak"],
+                  "mappings":[
+                      {
+                        "from":"1.1",
+                        "to":"Sars"
+                      },
+                      {
+                        "from":"1.2",
+                        "to":"Swine flue"
+                      },
+                      {
+                        "from":"1.3",
+                        "to":"Ebola"
+                      },
+                      {
+                        "from":"1.4",
+                        "to":"Zika"
+                      }
+                    ]
+                },
+                {
+                  "name":"A.x",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Outbreak"],
+                  "mappings":[
+                      {
+                        "from":"20.0",
+                        "to":"Sars"
+                      },
+                      {
+                        "from":"136.0625",
+                        "to":"Swine flue"
+                      },
+                      {
+                        "from":"252.125",
+                        "to":"Ebola"
+                      },
+                      {
+                        "from":"368.1875",
+                        "to":"Zika"
+                      }
+                    ]
+                },
+                {
+                  "name":"fill",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":true,
+                  "node":false,
+                  "labels":["Period"],
+                  "mappings":[
+                      {
+                        "from":"0x334db3ff",
+                        "to":"From start to paek"
+                      },
+                      {
+                        "from":"0x8099ffff",
+                        "to":"3 months after peak"
+                      },
+                      {
+                        "from":"0xb3ccffff",
+                        "to":"1 month after peak"
+                      }
+                    ]
+                },
+                {
+                  "name":"height",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Percentage change"],
+                  "function":"height/2"
+                },
+                {
+                  "name":"id",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["id"],
+                  "function":"id"
+                },
+                {
+                  "name":"x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["x"],
+                  "function":"x"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/UK-elections.json b/gallery/UK-elections.json
new file mode 100644
index 0000000000000000000000000000000000000000..939c0e9064859d2b361fadcaea5900ee1674c0b1
--- /dev/null
+++ b/gallery/UK-elections.json
@@ -0,0 +1,270 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":55.0,
+        "y":968.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+        "variable":["A.x","y","height"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":30.0,
+              "y":8.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":4.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":15.0,
+                    "height":44.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xccccccff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":48.0,
+                    "width":15.0,
+                    "height":10.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcccc33ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":62.0,
+                    "width":15.0,
+                    "height":148.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":214.0,
+                    "width":15.0,
+                    "height":96.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":475.0,
+              "y":8.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":4.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":15.0,
+                    "height":42.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xccccccff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":46.0,
+                    "width":15.0,
+                    "height":17.62962962962963,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcccc33ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":67.62962962962963,
+                    "width":15.0,
+                    "height":146.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":217.62962962962962,
+                    "width":15.0,
+                    "height":92.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            }
+          ],
+        "fill":"0xaaaabcff",
+        "opacity":0.20634920634920634,
+        "coloring":"Source",
+        "connections":[
+            {
+              "origin":"1.2",
+              "destination":"2.2",
+              "weight":10.0
+            },
+            {
+              "origin":"1.4",
+              "destination":"2.1",
+              "weight":2.0
+            },
+            {
+              "origin":"1.4",
+              "destination":"2.3",
+              "weight":4.0
+            },
+            {
+              "origin":"1.3",
+              "destination":"2.1",
+              "weight":4.0
+            },
+            {
+              "origin":"1.4",
+              "destination":"2.2",
+              "weight":6.0
+            },
+            {
+              "origin":"1.1",
+              "destination":"2.1",
+              "weight":36.0
+            },
+            {
+              "origin":"1.3",
+              "destination":"2.3",
+              "weight":140.0
+            },
+            {
+              "origin":"1.1",
+              "destination":"2.2",
+              "weight":1.6296296296296295
+            },
+            {
+              "origin":"1.3",
+              "destination":"2.4",
+              "weight":4.0
+            },
+            {
+              "origin":"1.4",
+              "destination":"2.4",
+              "weight":84.0
+            },
+            {
+              "origin":"1.1",
+              "destination":"2.4",
+              "weight":4.0
+            },
+            {
+              "origin":"1.1",
+              "destination":"2.3",
+              "weight":2.0
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/UK-elections.wrk b/gallery/UK-elections.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..8d04f493c7a29e8262287329809c862637e21c59
--- /dev/null
+++ b/gallery/UK-elections.wrk
@@ -0,0 +1,1936 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":96.875,
+            "y":785.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":90.0,
+            "y":871.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+            "variable":["x","y","width","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":125.0,
+                        "y":141.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":88.0,
+                        "y":76.0,
+                        "width":18.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":116.0,
+                        "y":36.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":206.0,
+                        "y":69.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":186.0,
+                        "y":114.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":266.0,
+                        "y":107.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":216.0,
+                        "y":141.0,
+                        "width":14.0,
+                        "height":14.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":300.0,
+                        "y":188.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":30.0,
+                        "y":56.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":67.0,
+                        "y":104.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":126.0,
+                        "y":68.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":164.0,
+                        "y":71.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":147.0,
+                        "y":116.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":257.0,
+                        "y":157.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":311.0,
+                        "y":149.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":237.0,
+                        "y":97.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":143.75,
+            "y":808.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Distance",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":44.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.y","x","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":44.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":88.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":132.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":176.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":122.0,
+            "y":908.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":29.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+            "variable":["x","height","fill"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":15.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":85.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xccccccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":44.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":129.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x808080ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":73.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":42.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e64dff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":102.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":68.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x80b380ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":494.0,
+            "y":913.0,
+            "sticky-y":"Yes",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["y","width"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2","reference-x3"],
+                ["reference-y1"],
+                ["reference-y2","reference-y3"],
+                ["x1","x2","x3"],
+                ["height1","height3"],
+                ["height2"],
+                ["shape1","shape2","shape3"],
+                ["fill1","fill3"],
+                ["fill2"],
+                ["stroke1","stroke2","stroke3"],
+                ["thickness1","thickness2","thickness3"],
+                ["rotation1","rotation2","rotation3"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Top",
+                  "x":0.0,
+                  "y":-41.0,
+                  "width":92.0,
+                  "height":10.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e699ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":2.0,
+                  "width":13.0,
+                  "height":86.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffe6ccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":50.0,
+                  "width":55.0,
+                  "height":10.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e699ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0x808080ff",
+            "x":136.0,
+            "y":972.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["x","y","height"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":20.0,
+                  "y":133.0,
+                  "width":25.0,
+                  "height":162.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":106.0,
+                  "y":80.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":193.0,
+                  "y":206.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":281.0,
+                  "y":135.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":277.0,
+                  "y":34.0,
+                  "width":25.0,
+                  "height":49.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ],
+            "fill":"0xcce6ffff",
+            "opacity":0.3015873015873016,
+            "coloring":"Source",
+            "connections":[
+                {
+                  "origin":"3",
+                  "destination":"4",
+                  "weight":81.0
+                },
+                {
+                  "origin":"1",
+                  "destination":"2",
+                  "weight":81.0
+                },
+                {
+                  "origin":"1",
+                  "destination":"3",
+                  "weight":81.0
+                },
+                {
+                  "origin":"2",
+                  "destination":"5",
+                  "weight":49.0
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":69.0,
+            "y":871.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":30.0,
+                  "y":8.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":16.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":15.0,
+                        "height":44.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xccccccff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":60.0,
+                        "width":15.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcccc33ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":15.0,
+                        "height":148.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":250.0,
+                        "width":15.0,
+                        "height":95.95851848710946,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":475.0,
+                  "y":8.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":16.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":15.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xccccccff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":58.0,
+                        "width":15.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcccc33ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":92.0,
+                        "width":15.0,
+                        "height":146.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":254.0,
+                        "width":15.0,
+                        "height":92.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ],
+            "fill":"0xaaaabcff",
+            "opacity":0.20634920634920634,
+            "coloring":"Source",
+            "connections":[
+                {
+                  "origin":"1.3",
+                  "destination":"2.3",
+                  "weight":138.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.1",
+                  "weight":30.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.2",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.1",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.1",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.3",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.4",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.2",
+                  "weight":1.9585184871094583
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.4",
+                  "weight":84.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.3",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.4",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.2",
+                  "destination":"2.2",
+                  "weight":10.0
+                }
+              ]
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Table",
+            "row":8,
+            "column":0,
+            "nrows":12,
+            "ncolumns":3,
+            "source":"1",
+            "group":"1",
+            "wide":true,
+            "network":true,
+            "properties":["id","id","weight"],
+            "variables":[
+                {
+                  "name":"id",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["source","destination"],
+                  "mappings":[
+                      {
+                        "from":"1.1.1",
+                        "to":"No control"
+                      },
+                      {
+                        "from":"1.1.2",
+                        "to":"Lib Dems"
+                      },
+                      {
+                        "from":"1.1.3",
+                        "to":"Labour"
+                      },
+                      {
+                        "from":"1.1.4",
+                        "to":"Conservative"
+                      },
+                      {
+                        "from":"1.2.1",
+                        "to":"No control"
+                      },
+                      {
+                        "from":"1.2.2",
+                        "to":"Lib Dems"
+                      },
+                      {
+                        "from":"1.2.3",
+                        "to":"Labour"
+                      },
+                      {
+                        "from":"1.2.4",
+                        "to":"Conservative"
+                      }
+                    ]
+                },
+                {
+                  "name":"weight",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Change"],
+                  "function":"weight/2"
+                }
+              ]
+          },
+          {
+            "type":"Table",
+            "row":24,
+            "column":0,
+            "nrows":8,
+            "ncolumns":6,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["A.id","id","A.x","y","height","fill"],
+            "variables":[
+                {
+                  "name":"A.id",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["A.id"],
+                  "mappings":[
+                      {
+                        "from":"1.1",
+                        "to":"Before 2018 Election"
+                      },
+                      {
+                        "from":"1.2",
+                        "to":"After 2018 Election"
+                      }
+                    ]
+                },
+                {
+                  "name":"A.x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["A.x"],
+                  "function":"A.x"
+                },
+                {
+                  "name":"fill",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["fill"],
+                  "function":"fill"
+                },
+                {
+                  "name":"height",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Control"],
+                  "function":"height/2"
+                },
+                {
+                  "name":"id",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["id"],
+                  "function":"id"
+                },
+                {
+                  "name":"y",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["y"],
+                  "function":"y"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/age-pyramid.json b/gallery/age-pyramid.json
new file mode 100644
index 0000000000000000000000000000000000000000..0e53ab97cbe7e0a89d59b9eb80505c830d059dbe
--- /dev/null
+++ b/gallery/age-pyramid.json
@@ -0,0 +1,409 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":223.0,
+        "y":1102.0,
+        "sticky-y":"No",
+        "sticky-x":"Yes",
+        "distribution-x":"None",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+        "variable":["y","width","fill"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":123.0,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":7.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["y","width"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":-34.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":23.0,
+                    "width":-57.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":46.0,
+                    "width":-75.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.4",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":69.0,
+                    "width":-105.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.5",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":92.0,
+                    "width":-90.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.6",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":115.0,
+                    "width":-64.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.7",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":138.0,
+                    "width":-36.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.8",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":161.0,
+                    "width":-29.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.9",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":184.0,
+                    "width":-23.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.10",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":207.0,
+                    "width":-18.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":123.0,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":7.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["y","width"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff6666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":23.0,
+                    "width":65.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff6666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":46.0,
+                    "width":126.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff6666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.4",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":69.0,
+                    "width":135.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff6666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.5",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":92.0,
+                    "width":100.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff6666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.6",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":115.0,
+                    "width":73.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff6666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.7",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":138.0,
+                    "width":48.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff6666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.8",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":161.0,
+                    "width":30.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff6666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.9",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":184.0,
+                    "width":24.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff6666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.10",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":207.0,
+                    "width":18.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff6666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/age-pyramid.wrk b/gallery/age-pyramid.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..a891b41184e9e2bb6031f12477e261c0504651c0
--- /dev/null
+++ b/gallery/age-pyramid.wrk
@@ -0,0 +1,1348 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":1004.0,
+            "y":1228.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":66.0,
+                  "height":62.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":72.0,
+                  "width":75.0,
+                  "height":19.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"my label",
+                  "fontsize":14.0,
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":978.0,
+            "y":803.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":-124.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x1","y","stroke","thickness","rotation"],
+            "variable":["width","height","shape","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["y1","y2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":106.0,
+                  "height":106.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff9999ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":78.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":222.5,
+            "y":1071.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":4.0,
+            "common":["reference-x","reference-y","x","shape","stroke","thickness","rotation"],
+            "variable":["y","width","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["shape1","shape2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":88.0,
+                  "height":12.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffccccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":16.0,
+                  "width":16.0,
+                  "height":91.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3ccffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":98.0,
+            "y":903.5,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":23.0,
+                  "y":14.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":16.0,
+                        "height":44.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xccccccff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":51.0,
+                        "width":16.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe666ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":68.0,
+                        "width":16.0,
+                        "height":148.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":223.0,
+                        "width":16.0,
+                        "height":96.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":406.0,
+                  "y":14.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":16.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xccccccff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":49.0,
+                        "width":16.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe666ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":74.0,
+                        "width":16.0,
+                        "height":146.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":227.0,
+                        "width":16.0,
+                        "height":92.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ],
+            "fill":"0xaaaabcff",
+            "opacity":0.3253968253968254,
+            "coloring":"Source",
+            "connections":[
+                {
+                  "origin":"1.1",
+                  "destination":"2.1",
+                  "weight":30.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.1",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.3",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.4",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.2",
+                  "destination":"2.2",
+                  "weight":10.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.4",
+                  "weight":84.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.2",
+                  "weight":6.3953488372093
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.1",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.2",
+                  "weight":2.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.3",
+                  "weight":138.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.4",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.3",
+                  "weight":4.0
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":204.0,
+            "y":990.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":5.0,
+            "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+            "variable":["y","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2","reference-x3"],
+                ["reference-y1","reference-y2","reference-y3"],
+                ["x1","x2","x3"],
+                ["width1","width2","width3"],
+                ["shape1","shape2"],
+                ["shape3"],
+                ["stroke1","stroke2","stroke3"],
+                ["thickness1","thickness2","thickness3"],
+                ["rotation1","rotation2","rotation3"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":83.0,
+                  "height":13.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x666666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":18.0,
+                  "width":83.0,
+                  "height":72.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffe666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Triangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":95.0,
+                  "width":83.0,
+                  "height":31.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff8080ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Triangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":223.0,
+            "y":1102.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+            "variable":["y","width","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":123.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":-34.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":23.0,
+                        "width":-57.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":46.0,
+                        "width":-75.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":69.0,
+                        "width":-105.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":92.0,
+                        "width":-90.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":115.0,
+                        "width":-64.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":138.0,
+                        "width":-36.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":161.0,
+                        "width":-29.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.9",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":184.0,
+                        "width":-23.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.10",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":207.0,
+                        "width":-18.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":123.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":23.0,
+                        "width":65.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":46.0,
+                        "width":126.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":69.0,
+                        "width":135.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":92.0,
+                        "width":100.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":115.0,
+                        "width":73.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":138.0,
+                        "width":48.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":161.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.9",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":184.0,
+                        "width":24.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.10",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":207.0,
+                        "width":18.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":223.0,
+            "y":1102.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+            "variable":["y","width","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":123.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":-34.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":23.0,
+                        "width":-57.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":46.0,
+                        "width":-75.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":69.0,
+                        "width":-105.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":92.0,
+                        "width":-90.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":115.0,
+                        "width":-64.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":138.0,
+                        "width":-36.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":161.0,
+                        "width":-29.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.9",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":184.0,
+                        "width":-23.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.10",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":207.0,
+                        "width":-18.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":123.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":23.0,
+                        "width":65.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":46.0,
+                        "width":126.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":69.0,
+                        "width":135.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":92.0,
+                        "width":100.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":115.0,
+                        "width":73.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":138.0,
+                        "width":48.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":161.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.9",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":184.0,
+                        "width":24.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.10",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":207.0,
+                        "width":18.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          }
+        ],
+      "datasheet":[]
+    }
+}
\ No newline at end of file
diff --git a/gallery/barchart-outbreaks.json b/gallery/barchart-outbreaks.json
new file mode 100644
index 0000000000000000000000000000000000000000..5f7e87114ff072169d7e4cad971943fda24cea04
--- /dev/null
+++ b/gallery/barchart-outbreaks.json
@@ -0,0 +1,317 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":125.5,
+        "y":1077.0,
+        "sticky-y":"No",
+        "sticky-x":"Yes",
+        "distribution-x":"Distance",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":105.625,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+        "variable":["A.x","x","height"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":21.375,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":27.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":-24.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x334db3ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":27.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":54.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcce6ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":54.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":75.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":127.0,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":27.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":-36.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x334db3ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":27.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":54.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcce6ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":54.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":75.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":232.625,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":27.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":-21.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x334db3ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":27.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcce6ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":54.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":26.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":338.0,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":27.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":-30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x334db3ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":27.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":28.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcce6ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":54.0,
+                    "y":0.0,
+                    "width":27.0,
+                    "height":116.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/barchart-outbreaks.wrk b/gallery/barchart-outbreaks.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..107efd7cf4bca4be590295891fe911c751993777
--- /dev/null
+++ b/gallery/barchart-outbreaks.wrk
@@ -0,0 +1,1115 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":96.875,
+            "y":785.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":90.0,
+            "y":871.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+            "variable":["x","y","width","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":125.0,
+                        "y":141.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":88.0,
+                        "y":76.0,
+                        "width":18.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":116.0,
+                        "y":36.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":206.0,
+                        "y":69.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":186.0,
+                        "y":114.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":266.0,
+                        "y":107.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":216.0,
+                        "y":141.0,
+                        "width":14.0,
+                        "height":14.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":300.0,
+                        "y":188.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":30.0,
+                        "y":56.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":67.0,
+                        "y":104.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":126.0,
+                        "y":68.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":164.0,
+                        "y":71.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":147.0,
+                        "y":116.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":257.0,
+                        "y":157.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":311.0,
+                        "y":149.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":237.0,
+                        "y":97.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":125.5,
+            "y":1077.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":105.625,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","x","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":21.375,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":27.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":-24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x334db3ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":27.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcce6ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":54.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":75.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":127.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":27.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":-36.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x334db3ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":27.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcce6ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":54.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":75.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":232.625,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":27.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":-21.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x334db3ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":27.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcce6ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":54.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":338.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":27.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":-30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x334db3ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":27.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":28.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcce6ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":54.0,
+                        "y":0.0,
+                        "width":27.0,
+                        "height":116.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Text",
+            "level":0,
+            "reference-x":"Left",
+            "reference-y":"Bottom",
+            "x":125.0,
+            "y":1231.0,
+            "width":299.0,
+            "height":19.0,
+            "rotation":0.0,
+            "fill":"0x696969ff",
+            "text":"Outbreak impact on market",
+            "fontsize":22.0,
+            "lock":"false"
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Table",
+            "row":5,
+            "column":0,
+            "nrows":12,
+            "ncolumns":6,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["A.id","id","A.x","x","height","fill"],
+            "variables":[
+                {
+                  "name":"A.id",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["A.id"],
+                  "function":"A.id"
+                },
+                {
+                  "name":"A.x",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Outbreak"],
+                  "mappings":[
+                      {
+                        "from":"21.375",
+                        "to":"Sars"
+                      },
+                      {
+                        "from":"127.0",
+                        "to":"Swine flu"
+                      },
+                      {
+                        "from":"232.625",
+                        "to":"Ebola"
+                      },
+                      {
+                        "from":"338.0",
+                        "to":"Zika"
+                      }
+                    ]
+                },
+                {
+                  "name":"fill",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":true,
+                  "node":false,
+                  "labels":["Period"],
+                  "mappings":[
+                      {
+                        "from":"0x334db3ff",
+                        "to":"From start to peak"
+                      },
+                      {
+                        "from":"0x8099ffff",
+                        "to":"3 months after peak"
+                      },
+                      {
+                        "from":"0xcce6ffff",
+                        "to":"1 month after peak"
+                      }
+                    ]
+                },
+                {
+                  "name":"height",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Change (%)"],
+                  "function":"height/3"
+                },
+                {
+                  "name":"id",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["id"],
+                  "function":"id"
+                },
+                {
+                  "name":"x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["x"],
+                  "function":"x"
+                }
+              ]
+          },
+          {
+            "type":"Value",
+            "row":20,
+            "column":2,
+            "nrows":1,
+            "ncolumns":2,
+            "source":"2",
+            "wide":true,
+            "network":false,
+            "properties":["text"],
+            "variables":[
+                {
+                  "name":"text",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Title"],
+                  "function":"text"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/bookshelf.json b/gallery/bookshelf.json
new file mode 100644
index 0000000000000000000000000000000000000000..b3f49efebd6799a00c21d4eff6307d260f88c97c
--- /dev/null
+++ b/gallery/bookshelf.json
@@ -0,0 +1,7289 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":5,
+        "prefix":"E.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":64.5,
+        "y":853.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"Spacing",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":40.0,
+        "curve":"None",
+        "common":["D.sticky-x","D.sticky-y","D.distribution-x","D.delta-x","D.distribution-y","D.delta-y","D.x","D.curve","D.stroke","D.thickness","D.rotation","C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+        "variable":["D.y","C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":4,
+              "prefix":"D.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":7.0,
+              "y":13.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"Spacing",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":15.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+              "variable":["C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","fill1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+              "components":[
+                  {
+                    "type":"Collection",
+                    "id":"1.1",
+                    "level":3,
+                    "prefix":"C.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":20.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"Spacing",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"None",
+                    "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                    "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"1.1.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":0.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.1.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":57.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":26.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.1.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.1.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.1.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"1.1.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":48.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.1.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.2.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":49.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.1.2.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.2.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.2.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.2.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"1.1.3",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":96.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.1.3.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.3.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":91.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.3.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":27.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.1.3.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.3.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.3.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.3.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"1.1.4",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":150.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.1.4.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.4.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":60.0,
+                                      "height":57.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.4.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":60.0,
+                                      "height":21.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.1.4.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.4.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.4.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.4.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"1.1.5",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":204.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.1.5.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.5.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.5.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.1.5.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.5.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.5.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.5.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  },
+                  {
+                    "type":"Collection",
+                    "id":"1.2",
+                    "level":3,
+                    "prefix":"C.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":283.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"Spacing",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"None",
+                    "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                    "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"1.2.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":0.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.2.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":40.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":40.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.2.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.1.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.1.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"1.2.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":44.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.2.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":65.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.2.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":20.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.2.2.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.2.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.2.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.2.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"1.2.3",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":85.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.2.3.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.3.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":82.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.3.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.2.3.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.3.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.3.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.3.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"1.2.4",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":121.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.2.4.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.4.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":38.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.4.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":38.0,
+                                      "height":21.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.2.4.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.4.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.4.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.4.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"1.2.5",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":158.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.2.5.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.5.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":36.0,
+                                      "height":59.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.5.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":36.0,
+                                      "height":24.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.2.5.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.5.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.5.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.5.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":4,
+              "prefix":"D.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":7.0,
+              "y":144.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"Spacing",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":15.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+              "variable":["C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","fill1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+              "components":[
+                  {
+                    "type":"Collection",
+                    "id":"2.1",
+                    "level":3,
+                    "prefix":"C.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":20.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"Spacing",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"None",
+                    "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                    "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"2.1.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":0.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.1.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.1.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.1.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.1.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"2.1.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":48.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.1.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.2.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":49.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.1.2.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.2.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.2.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.2.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"2.1.3",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":96.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.1.3.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.3.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":27.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.3.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":13.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.1.3.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.3.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.3.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.3.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"2.1.4",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":150.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.1.4.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.4.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":60.0,
+                                      "height":39.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.4.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":60.0,
+                                      "height":21.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.1.4.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.4.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.4.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.4.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"2.1.5",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":190.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.1.5.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.5.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":20.0,
+                                      "height":60.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.5.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":20.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.1.5.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.5.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.5.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.5.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  },
+                  {
+                    "type":"Collection",
+                    "id":"2.2",
+                    "level":3,
+                    "prefix":"C.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":255.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"Spacing",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"None",
+                    "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                    "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"2.2.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":0.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.2.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":40.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":40.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.2.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.1.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.1.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"2.2.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":44.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.2.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":65.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.2.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":20.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.2.2.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.2.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.2.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.2.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"2.2.3",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":85.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.2.3.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.3.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":85.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.3.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.2.3.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.3.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.3.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.3.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"2.2.4",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":121.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.2.4.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.4.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":38.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.4.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":38.0,
+                                      "height":21.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.2.4.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.4.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.4.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.4.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"2.2.5",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":156.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.2.5.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.5.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":32.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.5.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":32.0,
+                                      "height":24.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.2.5.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.5.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.5.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.5.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"3",
+              "level":4,
+              "prefix":"D.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":7.0,
+              "y":269.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"Spacing",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":15.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+              "variable":["C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","fill1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+              "components":[
+                  {
+                    "type":"Collection",
+                    "id":"3.1",
+                    "level":3,
+                    "prefix":"C.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":20.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"Spacing",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"None",
+                    "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                    "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"3.1.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":0.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.1.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":56.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.1.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.1.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.1.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"3.1.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":39.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.1.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":30.0,
+                                      "height":65.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.2.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":30.0,
+                                      "height":49.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.1.2.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.2.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.2.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.2.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"3.1.3",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":71.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.1.3.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.3.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":60.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.3.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.1.3.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.3.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.3.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.3.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"3.1.4",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":118.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.1.4.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.4.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":60.0,
+                                      "height":57.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.4.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":60.0,
+                                      "height":21.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.1.4.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.4.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.4.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.4.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"3.1.5",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":181.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.1.5.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.5.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":66.0,
+                                      "height":48.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.5.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":66.0,
+                                      "height":11.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.1.5.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.5.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.5.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.5.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  },
+                  {
+                    "type":"Collection",
+                    "id":"3.2",
+                    "level":3,
+                    "prefix":"C.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":269.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"Spacing",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"None",
+                    "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                    "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"3.2.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":0.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.2.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":40.0,
+                                      "height":52.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":40.0,
+                                      "height":24.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.2.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.1.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.1.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"3.2.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":44.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.2.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":65.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.2.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":20.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.2.2.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.2.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.2.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.2.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"3.2.3",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":85.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.2.3.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.3.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":76.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.3.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.2.3.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.3.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.3.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.3.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"3.2.4",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":121.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.2.4.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.4.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":38.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.4.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":38.0,
+                                      "height":21.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.2.4.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.4.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.4.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.4.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"3.2.5",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":155.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.2.5.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.5.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":30.0,
+                                      "height":48.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.5.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":30.0,
+                                      "height":24.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.2.5.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.5.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.5.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.5.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"4",
+              "level":4,
+              "prefix":"D.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":7.0,
+              "y":389.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"Spacing",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":15.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+              "variable":["C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","fill1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+              "components":[
+                  {
+                    "type":"Collection",
+                    "id":"4.1",
+                    "level":3,
+                    "prefix":"C.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":20.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"Spacing",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"None",
+                    "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                    "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"4.1.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":0.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"4.1.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"4.1.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.1.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.1.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"4.1.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":41.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"4.1.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":58.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.2.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":18.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"4.1.2.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.2.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.2.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.2.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"4.1.3",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":82.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"4.1.3.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.3.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":61.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.3.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"4.1.3.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.3.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.3.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.3.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"4.1.4",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":136.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"4.1.4.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.4.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":60.0,
+                                      "height":57.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.4.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":60.0,
+                                      "height":21.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"4.1.4.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.4.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.4.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.4.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"4.1.5",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":189.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"4.1.5.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.5.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":46.0,
+                                      "height":80.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xb3e6b3ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.5.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":46.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"4.1.5.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.5.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.5.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.1.5.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  },
+                  {
+                    "type":"Collection",
+                    "id":"4.2",
+                    "level":3,
+                    "prefix":"C.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":267.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"Spacing",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"None",
+                    "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                    "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"4.2.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":0.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"4.2.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":40.0,
+                                      "height":63.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":40.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"4.2.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.1.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.1.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"4.2.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":44.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"4.2.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":65.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.2.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":48.0,
+                                      "height":20.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"4.2.2.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.2.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.2.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.2.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"4.2.3",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":85.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"4.2.3.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.3.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":52.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.3.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":34.0,
+                                      "height":37.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"4.2.3.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.3.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.3.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.3.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"4.2.4",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":121.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"4.2.4.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.4.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":38.0,
+                                      "height":45.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.4.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":38.0,
+                                      "height":21.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"4.2.4.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.4.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.4.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.4.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":14.0,
+                                      "height":14.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"4.2.5",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":158.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":-31.0,
+                          "delta-y":0.0,
+                          "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "variable":["A.sticky-x"],
+                          "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                          "bindings":[
+                              ["A.sticky-y1","A.sticky-y2"],
+                              ["A.distribution-x1","A.distribution-x2"],
+                              ["A.delta-x1","A.delta-x2"],
+                              ["A.distribution-y1","A.distribution-y2"],
+                              ["A.delta-y1","A.delta-y2"],
+                              ["A.x1","A.x2"],
+                              ["A.y1","A.y2"],
+                              ["A.rotation1","A.rotation2"],
+                              ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                              ["reference-y1.1","reference-y1.2"],
+                              ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                              ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                              ["y1.1","y1.2"],
+                              ["y2.1","y2.2","y2.3"],
+                              ["width1.1","width1.2"],
+                              ["width2.1","width2.2","width2.3"],
+                              ["height1.1"],
+                              ["height1.2"],
+                              ["height2.1","height2.2","height2.3"],
+                              ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                              ["fill1.1"],
+                              ["fill1.2"],
+                              ["fill2.1","fill2.2","fill2.3"],
+                              ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                              ["thickness1.1"],
+                              ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                              ["rotation1.1","rotation1.2"],
+                              ["rotation2.1"],
+                              ["rotation2.2"],
+                              ["rotation2.3"]
+                            ],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"4.2.5.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"Yes",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x1.1","y1.1"],
+                                "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.5.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":36.0,
+                                      "height":66.0,
+                                      "thickness":1.1349206349206349,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.5.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":36.0,
+                                      "height":13.0,
+                                      "thickness":0.0,
+                                      "rotation":0.0,
+                                      "fill":"0x4d4d4d64",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"4.2.5.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"Yes",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["x2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.5.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":45.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.5.2.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"4.2.5.2.3",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Center",
+                                      "x":0.0,
+                                      "y":16.0,
+                                      "width":0.0,
+                                      "height":0.0,
+                                      "thickness":0.0,
+                                      "rotation":-12.0,
+                                      "fill":"0x333333ff",
+                                      "stroke":"0x4d4d4dff",
+                                      "shape":"Rectangle",
+                                      "lock":"true"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/bookshelf.wrk b/gallery/bookshelf.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..c64f5fde8c9274aa400c56fdba16fb3dba126959
--- /dev/null
+++ b/gallery/bookshelf.wrk
@@ -0,0 +1,10622 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":1004.0,
+            "y":1228.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":66.0,
+                  "height":62.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":72.0,
+                  "width":75.0,
+                  "height":19.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"my label",
+                  "fontsize":14.0,
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":1004.0,
+            "y":935.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+            "variable":["y","width","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":-72.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":-82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":-89.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":-93.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":-51.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":-26.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":86.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":103.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":125.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":66.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":36.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":9.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":978.0,
+            "y":803.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":-124.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x1","y","stroke","thickness","rotation"],
+            "variable":["width","height","shape","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["y1","y2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":106.0,
+                  "height":106.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff9999ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":78.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":3,
+            "prefix":"C.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":255.0,
+            "y":0.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"Spacing",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+            "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+            "components":[
+                {
+                  "type":"Group",
+                  "id":"1",
+                  "level":2,
+                  "prefix":"B.",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":-31.0,
+                  "delta-y":0.0,
+                  "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["A.sticky-x"],
+                  "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                  "bindings":[
+                      ["A.sticky-y1","A.sticky-y2"],
+                      ["A.distribution-x1","A.distribution-x2"],
+                      ["A.delta-x1","A.delta-x2"],
+                      ["A.distribution-y1","A.distribution-y2"],
+                      ["A.delta-y1","A.delta-y2"],
+                      ["A.x1","A.x2"],
+                      ["A.y1","A.y2"],
+                      ["A.rotation1","A.rotation2"],
+                      ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                      ["reference-y1.1","reference-y1.2"],
+                      ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                      ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                      ["y1.1","y1.2"],
+                      ["y2.1","y2.2","y2.3"],
+                      ["width1.1","width1.2"],
+                      ["width2.1","width2.2","width2.3"],
+                      ["height1.1"],
+                      ["height1.2"],
+                      ["height2.1","height2.2","height2.3"],
+                      ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                      ["fill1.1"],
+                      ["fill1.2"],
+                      ["fill2.1","fill2.2","fill2.3"],
+                      ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                      ["thickness1.1"],
+                      ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                      ["rotation1.1","rotation1.2"],
+                      ["rotation2.1"],
+                      ["rotation2.2"],
+                      ["rotation2.3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Group",
+                        "id":"1.1",
+                        "level":1,
+                        "prefix":"A.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":20.0,
+                        "delta-y":0.0,
+                        "common":["x1.1","y1.1"],
+                        "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":40.0,
+                              "height":80.0,
+                              "thickness":1.1349206349206349,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":40.0,
+                              "height":37.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x4d4d4d64",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"1.2",
+                        "level":1,
+                        "prefix":"A.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"No",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":20.0,
+                        "delta-y":0.0,
+                        "common":["x2.1"],
+                        "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":45.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":12.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.3",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":-12.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"2",
+                  "level":2,
+                  "prefix":"B.",
+                  "x":44.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":-31.0,
+                  "delta-y":0.0,
+                  "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["A.sticky-x"],
+                  "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                  "bindings":[
+                      ["A.sticky-y1","A.sticky-y2"],
+                      ["A.distribution-x1","A.distribution-x2"],
+                      ["A.delta-x1","A.delta-x2"],
+                      ["A.distribution-y1","A.distribution-y2"],
+                      ["A.delta-y1","A.delta-y2"],
+                      ["A.x1","A.x2"],
+                      ["A.y1","A.y2"],
+                      ["A.rotation1","A.rotation2"],
+                      ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                      ["reference-y1.1","reference-y1.2"],
+                      ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                      ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                      ["y1.1","y1.2"],
+                      ["y2.1","y2.2","y2.3"],
+                      ["width1.1","width1.2"],
+                      ["width2.1","width2.2","width2.3"],
+                      ["height1.1"],
+                      ["height1.2"],
+                      ["height2.1","height2.2","height2.3"],
+                      ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                      ["fill1.1"],
+                      ["fill1.2"],
+                      ["fill2.1","fill2.2","fill2.3"],
+                      ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                      ["thickness1.1"],
+                      ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                      ["rotation1.1","rotation1.2"],
+                      ["rotation2.1"],
+                      ["rotation2.2"],
+                      ["rotation2.3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Group",
+                        "id":"2.1",
+                        "level":1,
+                        "prefix":"A.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":20.0,
+                        "delta-y":0.0,
+                        "common":["x1.1","y1.1"],
+                        "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":48.0,
+                              "height":65.0,
+                              "thickness":1.1349206349206349,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":48.0,
+                              "height":20.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x4d4d4d64",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"2.2",
+                        "level":1,
+                        "prefix":"A.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"No",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":20.0,
+                        "delta-y":0.0,
+                        "common":["x2.1"],
+                        "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":45.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":12.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.3",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":-12.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"3",
+                  "level":2,
+                  "prefix":"B.",
+                  "x":85.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":-31.0,
+                  "delta-y":0.0,
+                  "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["A.sticky-x"],
+                  "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                  "bindings":[
+                      ["A.sticky-y1","A.sticky-y2"],
+                      ["A.distribution-x1","A.distribution-x2"],
+                      ["A.delta-x1","A.delta-x2"],
+                      ["A.distribution-y1","A.distribution-y2"],
+                      ["A.delta-y1","A.delta-y2"],
+                      ["A.x1","A.x2"],
+                      ["A.y1","A.y2"],
+                      ["A.rotation1","A.rotation2"],
+                      ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                      ["reference-y1.1","reference-y1.2"],
+                      ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                      ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                      ["y1.1","y1.2"],
+                      ["y2.1","y2.2","y2.3"],
+                      ["width1.1","width1.2"],
+                      ["width2.1","width2.2","width2.3"],
+                      ["height1.1"],
+                      ["height1.2"],
+                      ["height2.1","height2.2","height2.3"],
+                      ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                      ["fill1.1"],
+                      ["fill1.2"],
+                      ["fill2.1","fill2.2","fill2.3"],
+                      ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                      ["thickness1.1"],
+                      ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                      ["rotation1.1","rotation1.2"],
+                      ["rotation2.1"],
+                      ["rotation2.2"],
+                      ["rotation2.3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Group",
+                        "id":"3.1",
+                        "level":1,
+                        "prefix":"A.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":20.0,
+                        "delta-y":0.0,
+                        "common":["x1.1","y1.1"],
+                        "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":34.0,
+                              "height":85.0,
+                              "thickness":1.1349206349206349,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":34.0,
+                              "height":37.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x4d4d4d64",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"3.2",
+                        "level":1,
+                        "prefix":"A.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"No",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":20.0,
+                        "delta-y":0.0,
+                        "common":["x2.1"],
+                        "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":45.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":12.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.3",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":-12.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"4",
+                  "level":2,
+                  "prefix":"B.",
+                  "x":121.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":-31.0,
+                  "delta-y":0.0,
+                  "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["A.sticky-x"],
+                  "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                  "bindings":[
+                      ["A.sticky-y1","A.sticky-y2"],
+                      ["A.distribution-x1","A.distribution-x2"],
+                      ["A.delta-x1","A.delta-x2"],
+                      ["A.distribution-y1","A.distribution-y2"],
+                      ["A.delta-y1","A.delta-y2"],
+                      ["A.x1","A.x2"],
+                      ["A.y1","A.y2"],
+                      ["A.rotation1","A.rotation2"],
+                      ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                      ["reference-y1.1","reference-y1.2"],
+                      ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                      ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                      ["y1.1","y1.2"],
+                      ["y2.1","y2.2","y2.3"],
+                      ["width1.1","width1.2"],
+                      ["width2.1","width2.2","width2.3"],
+                      ["height1.1"],
+                      ["height1.2"],
+                      ["height2.1","height2.2","height2.3"],
+                      ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                      ["fill1.1"],
+                      ["fill1.2"],
+                      ["fill2.1","fill2.2","fill2.3"],
+                      ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                      ["thickness1.1"],
+                      ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                      ["rotation1.1","rotation1.2"],
+                      ["rotation2.1"],
+                      ["rotation2.2"],
+                      ["rotation2.3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Group",
+                        "id":"4.1",
+                        "level":1,
+                        "prefix":"A.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":20.0,
+                        "delta-y":0.0,
+                        "common":["x1.1","y1.1"],
+                        "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"4.1.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":38.0,
+                              "height":80.0,
+                              "thickness":1.1349206349206349,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"4.1.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":38.0,
+                              "height":21.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x4d4d4d64",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"4.2",
+                        "level":1,
+                        "prefix":"A.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"No",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":20.0,
+                        "delta-y":0.0,
+                        "common":["x2.1"],
+                        "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"4.2.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":45.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"4.2.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":12.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"4.2.3",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":0.0,
+                              "height":0.0,
+                              "thickness":0.0,
+                              "rotation":-12.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"5",
+                  "level":2,
+                  "prefix":"B.",
+                  "x":156.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":-31.0,
+                  "delta-y":0.0,
+                  "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["A.sticky-x"],
+                  "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                  "bindings":[
+                      ["A.sticky-y1","A.sticky-y2"],
+                      ["A.distribution-x1","A.distribution-x2"],
+                      ["A.delta-x1","A.delta-x2"],
+                      ["A.distribution-y1","A.distribution-y2"],
+                      ["A.delta-y1","A.delta-y2"],
+                      ["A.x1","A.x2"],
+                      ["A.y1","A.y2"],
+                      ["A.rotation1","A.rotation2"],
+                      ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                      ["reference-y1.1","reference-y1.2"],
+                      ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                      ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                      ["y1.1","y1.2"],
+                      ["y2.1","y2.2","y2.3"],
+                      ["width1.1","width1.2"],
+                      ["width2.1","width2.2","width2.3"],
+                      ["height1.1"],
+                      ["height1.2"],
+                      ["height2.1","height2.2","height2.3"],
+                      ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                      ["fill1.1"],
+                      ["fill1.2"],
+                      ["fill2.1","fill2.2","fill2.3"],
+                      ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                      ["thickness1.1"],
+                      ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                      ["rotation1.1","rotation1.2"],
+                      ["rotation2.1"],
+                      ["rotation2.2"],
+                      ["rotation2.3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Group",
+                        "id":"5.1",
+                        "level":1,
+                        "prefix":"A.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":20.0,
+                        "delta-y":0.0,
+                        "common":["x1.1","y1.1"],
+                        "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"5.1.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":32.0,
+                              "height":80.0,
+                              "thickness":1.1349206349206349,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"5.1.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":32.0,
+                              "height":24.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x4d4d4d64",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"5.2",
+                        "level":1,
+                        "prefix":"A.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"No",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":20.0,
+                        "delta-y":0.0,
+                        "common":["x2.1"],
+                        "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"5.2.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":14.0,
+                              "height":14.0,
+                              "thickness":0.0,
+                              "rotation":45.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"5.2.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":14.0,
+                              "height":14.0,
+                              "thickness":0.0,
+                              "rotation":12.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"5.2.3",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Center",
+                              "x":0.0,
+                              "y":16.0,
+                              "width":14.0,
+                              "height":14.0,
+                              "thickness":0.0,
+                              "rotation":-12.0,
+                              "fill":"0x333333ff",
+                              "stroke":"0x4d4d4dff",
+                              "shape":"Rectangle",
+                              "lock":"true"
+                            }
+                          ]
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":4,
+            "prefix":"D.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":7.0,
+            "y":13.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Spacing",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":15.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+            "variable":["C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","fill1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":3,
+                  "prefix":"C.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":20.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                  "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                  "components":[
+                      {
+                        "type":"Group",
+                        "id":"1.1",
+                        "level":2,
+                        "prefix":"B.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":-31.0,
+                        "delta-y":0.0,
+                        "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["A.sticky-x"],
+                        "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                        "bindings":[
+                            ["A.sticky-y1","A.sticky-y2"],
+                            ["A.distribution-x1","A.distribution-x2"],
+                            ["A.delta-x1","A.delta-x2"],
+                            ["A.distribution-y1","A.distribution-y2"],
+                            ["A.delta-y1","A.delta-y2"],
+                            ["A.x1","A.x2"],
+                            ["A.y1","A.y2"],
+                            ["A.rotation1","A.rotation2"],
+                            ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                            ["reference-y1.1","reference-y1.2"],
+                            ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                            ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                            ["y1.1","y1.2"],
+                            ["y2.1","y2.2","y2.3"],
+                            ["width1.1","width1.2"],
+                            ["width2.1","width2.2","width2.3"],
+                            ["height1.1"],
+                            ["height1.2"],
+                            ["height2.1","height2.2","height2.3"],
+                            ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                            ["fill1.1"],
+                            ["fill1.2"],
+                            ["fill2.1","fill2.2","fill2.3"],
+                            ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                            ["thickness1.1"],
+                            ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                            ["rotation1.1","rotation1.2"],
+                            ["rotation2.1"],
+                            ["rotation2.2"],
+                            ["rotation2.3"]
+                          ],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"1.1.1",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x1.1","y1.1"],
+                              "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.1.1.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":48.0,
+                                    "height":57.0,
+                                    "thickness":1.1349206349206349,
+                                    "rotation":0.0,
+                                    "fill":"0xb3e6b3ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.1.1.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":48.0,
+                                    "height":26.0,
+                                    "thickness":0.0,
+                                    "rotation":0.0,
+                                    "fill":"0x4d4d4d64",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.1.2",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"No",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x2.1"],
+                              "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.1.2.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":45.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.1.2.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.1.2.3",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":-12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"1.2",
+                        "level":2,
+                        "prefix":"B.",
+                        "x":48.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":-31.0,
+                        "delta-y":0.0,
+                        "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["A.sticky-x"],
+                        "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                        "bindings":[
+                            ["A.sticky-y1","A.sticky-y2"],
+                            ["A.distribution-x1","A.distribution-x2"],
+                            ["A.delta-x1","A.delta-x2"],
+                            ["A.distribution-y1","A.distribution-y2"],
+                            ["A.delta-y1","A.delta-y2"],
+                            ["A.x1","A.x2"],
+                            ["A.y1","A.y2"],
+                            ["A.rotation1","A.rotation2"],
+                            ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                            ["reference-y1.1","reference-y1.2"],
+                            ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                            ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                            ["y1.1","y1.2"],
+                            ["y2.1","y2.2","y2.3"],
+                            ["width1.1","width1.2"],
+                            ["width2.1","width2.2","width2.3"],
+                            ["height1.1"],
+                            ["height1.2"],
+                            ["height2.1","height2.2","height2.3"],
+                            ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                            ["fill1.1"],
+                            ["fill1.2"],
+                            ["fill2.1","fill2.2","fill2.3"],
+                            ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                            ["thickness1.1"],
+                            ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                            ["rotation1.1","rotation1.2"],
+                            ["rotation2.1"],
+                            ["rotation2.2"],
+                            ["rotation2.3"]
+                          ],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"1.2.1",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x1.1","y1.1"],
+                              "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.2.1.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":48.0,
+                                    "height":80.0,
+                                    "thickness":1.1349206349206349,
+                                    "rotation":0.0,
+                                    "fill":"0xb3e6b3ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.2.1.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":48.0,
+                                    "height":49.0,
+                                    "thickness":0.0,
+                                    "rotation":0.0,
+                                    "fill":"0x4d4d4d64",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.2.2",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"No",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x2.1"],
+                              "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.2.2.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":14.0,
+                                    "height":14.0,
+                                    "thickness":0.0,
+                                    "rotation":45.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.2.2.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":14.0,
+                                    "height":14.0,
+                                    "thickness":0.0,
+                                    "rotation":12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.2.2.3",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":14.0,
+                                    "height":14.0,
+                                    "thickness":0.0,
+                                    "rotation":-12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"1.3",
+                        "level":2,
+                        "prefix":"B.",
+                        "x":96.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":-31.0,
+                        "delta-y":0.0,
+                        "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["A.sticky-x"],
+                        "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                        "bindings":[
+                            ["A.sticky-y1","A.sticky-y2"],
+                            ["A.distribution-x1","A.distribution-x2"],
+                            ["A.delta-x1","A.delta-x2"],
+                            ["A.distribution-y1","A.distribution-y2"],
+                            ["A.delta-y1","A.delta-y2"],
+                            ["A.x1","A.x2"],
+                            ["A.y1","A.y2"],
+                            ["A.rotation1","A.rotation2"],
+                            ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                            ["reference-y1.1","reference-y1.2"],
+                            ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                            ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                            ["y1.1","y1.2"],
+                            ["y2.1","y2.2","y2.3"],
+                            ["width1.1","width1.2"],
+                            ["width2.1","width2.2","width2.3"],
+                            ["height1.1"],
+                            ["height1.2"],
+                            ["height2.1","height2.2","height2.3"],
+                            ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                            ["fill1.1"],
+                            ["fill1.2"],
+                            ["fill2.1","fill2.2","fill2.3"],
+                            ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                            ["thickness1.1"],
+                            ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                            ["rotation1.1","rotation1.2"],
+                            ["rotation2.1"],
+                            ["rotation2.2"],
+                            ["rotation2.3"]
+                          ],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"1.3.1",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x1.1","y1.1"],
+                              "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.3.1.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":48.0,
+                                    "height":91.0,
+                                    "thickness":1.1349206349206349,
+                                    "rotation":0.0,
+                                    "fill":"0xb3e6b3ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.3.1.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":48.0,
+                                    "height":27.0,
+                                    "thickness":0.0,
+                                    "rotation":0.0,
+                                    "fill":"0x4d4d4d64",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.3.2",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"No",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x2.1"],
+                              "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.3.2.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":45.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.3.2.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.3.2.3",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":-12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"1.4",
+                        "level":2,
+                        "prefix":"B.",
+                        "x":150.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":-31.0,
+                        "delta-y":0.0,
+                        "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["A.sticky-x"],
+                        "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                        "bindings":[
+                            ["A.sticky-y1","A.sticky-y2"],
+                            ["A.distribution-x1","A.distribution-x2"],
+                            ["A.delta-x1","A.delta-x2"],
+                            ["A.distribution-y1","A.distribution-y2"],
+                            ["A.delta-y1","A.delta-y2"],
+                            ["A.x1","A.x2"],
+                            ["A.y1","A.y2"],
+                            ["A.rotation1","A.rotation2"],
+                            ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                            ["reference-y1.1","reference-y1.2"],
+                            ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                            ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                            ["y1.1","y1.2"],
+                            ["y2.1","y2.2","y2.3"],
+                            ["width1.1","width1.2"],
+                            ["width2.1","width2.2","width2.3"],
+                            ["height1.1"],
+                            ["height1.2"],
+                            ["height2.1","height2.2","height2.3"],
+                            ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                            ["fill1.1"],
+                            ["fill1.2"],
+                            ["fill2.1","fill2.2","fill2.3"],
+                            ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                            ["thickness1.1"],
+                            ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                            ["rotation1.1","rotation1.2"],
+                            ["rotation2.1"],
+                            ["rotation2.2"],
+                            ["rotation2.3"]
+                          ],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"1.4.1",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x1.1","y1.1"],
+                              "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.4.1.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":60.0,
+                                    "height":57.0,
+                                    "thickness":1.1349206349206349,
+                                    "rotation":0.0,
+                                    "fill":"0xb3e6b3ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.4.1.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":60.0,
+                                    "height":21.0,
+                                    "thickness":0.0,
+                                    "rotation":0.0,
+                                    "fill":"0x4d4d4d64",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.4.2",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"No",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x2.1"],
+                              "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.4.2.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":14.0,
+                                    "height":14.0,
+                                    "thickness":0.0,
+                                    "rotation":45.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.4.2.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":14.0,
+                                    "height":14.0,
+                                    "thickness":0.0,
+                                    "rotation":12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.4.2.3",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":14.0,
+                                    "height":14.0,
+                                    "thickness":0.0,
+                                    "rotation":-12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"1.5",
+                        "level":2,
+                        "prefix":"B.",
+                        "x":204.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":-31.0,
+                        "delta-y":0.0,
+                        "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["A.sticky-x"],
+                        "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                        "bindings":[
+                            ["A.sticky-y1","A.sticky-y2"],
+                            ["A.distribution-x1","A.distribution-x2"],
+                            ["A.delta-x1","A.delta-x2"],
+                            ["A.distribution-y1","A.distribution-y2"],
+                            ["A.delta-y1","A.delta-y2"],
+                            ["A.x1","A.x2"],
+                            ["A.y1","A.y2"],
+                            ["A.rotation1","A.rotation2"],
+                            ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                            ["reference-y1.1","reference-y1.2"],
+                            ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                            ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                            ["y1.1","y1.2"],
+                            ["y2.1","y2.2","y2.3"],
+                            ["width1.1","width1.2"],
+                            ["width2.1","width2.2","width2.3"],
+                            ["height1.1"],
+                            ["height1.2"],
+                            ["height2.1","height2.2","height2.3"],
+                            ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                            ["fill1.1"],
+                            ["fill1.2"],
+                            ["fill2.1","fill2.2","fill2.3"],
+                            ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                            ["thickness1.1"],
+                            ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                            ["rotation1.1","rotation1.2"],
+                            ["rotation2.1"],
+                            ["rotation2.2"],
+                            ["rotation2.3"]
+                          ],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"1.5.1",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x1.1","y1.1"],
+                              "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.5.1.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":48.0,
+                                    "height":80.0,
+                                    "thickness":1.1349206349206349,
+                                    "rotation":0.0,
+                                    "fill":"0xb3e6b3ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.5.1.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":48.0,
+                                    "height":37.0,
+                                    "thickness":0.0,
+                                    "rotation":0.0,
+                                    "fill":"0x4d4d4d64",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.5.2",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"No",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x2.1"],
+                              "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.5.2.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":45.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.5.2.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"1.5.2.3",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":-12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  }
+                                ]
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":3,
+                  "prefix":"C.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":283.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                  "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                  "components":[
+                      {
+                        "type":"Group",
+                        "id":"2.1",
+                        "level":2,
+                        "prefix":"B.",
+                        "x":0.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":-31.0,
+                        "delta-y":0.0,
+                        "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["A.sticky-x"],
+                        "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                        "bindings":[
+                            ["A.sticky-y1","A.sticky-y2"],
+                            ["A.distribution-x1","A.distribution-x2"],
+                            ["A.delta-x1","A.delta-x2"],
+                            ["A.distribution-y1","A.distribution-y2"],
+                            ["A.delta-y1","A.delta-y2"],
+                            ["A.x1","A.x2"],
+                            ["A.y1","A.y2"],
+                            ["A.rotation1","A.rotation2"],
+                            ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                            ["reference-y1.1","reference-y1.2"],
+                            ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                            ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                            ["y1.1","y1.2"],
+                            ["y2.1","y2.2","y2.3"],
+                            ["width1.1","width1.2"],
+                            ["width2.1","width2.2","width2.3"],
+                            ["height1.1"],
+                            ["height1.2"],
+                            ["height2.1","height2.2","height2.3"],
+                            ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                            ["fill1.1"],
+                            ["fill1.2"],
+                            ["fill2.1","fill2.2","fill2.3"],
+                            ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                            ["thickness1.1"],
+                            ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                            ["rotation1.1","rotation1.2"],
+                            ["rotation2.1"],
+                            ["rotation2.2"],
+                            ["rotation2.3"]
+                          ],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"2.1.1",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x1.1","y1.1"],
+                              "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.1.1.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":40.0,
+                                    "height":80.0,
+                                    "thickness":1.1349206349206349,
+                                    "rotation":0.0,
+                                    "fill":"0xe64d4dff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.1.1.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":40.0,
+                                    "height":37.0,
+                                    "thickness":0.0,
+                                    "rotation":0.0,
+                                    "fill":"0x4d4d4d64",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.1.2",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"No",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x2.1"],
+                              "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.1.2.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":45.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.1.2.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.1.2.3",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":-12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"2.2",
+                        "level":2,
+                        "prefix":"B.",
+                        "x":44.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":-31.0,
+                        "delta-y":0.0,
+                        "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["A.sticky-x"],
+                        "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                        "bindings":[
+                            ["A.sticky-y1","A.sticky-y2"],
+                            ["A.distribution-x1","A.distribution-x2"],
+                            ["A.delta-x1","A.delta-x2"],
+                            ["A.distribution-y1","A.distribution-y2"],
+                            ["A.delta-y1","A.delta-y2"],
+                            ["A.x1","A.x2"],
+                            ["A.y1","A.y2"],
+                            ["A.rotation1","A.rotation2"],
+                            ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                            ["reference-y1.1","reference-y1.2"],
+                            ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                            ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                            ["y1.1","y1.2"],
+                            ["y2.1","y2.2","y2.3"],
+                            ["width1.1","width1.2"],
+                            ["width2.1","width2.2","width2.3"],
+                            ["height1.1"],
+                            ["height1.2"],
+                            ["height2.1","height2.2","height2.3"],
+                            ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                            ["fill1.1"],
+                            ["fill1.2"],
+                            ["fill2.1","fill2.2","fill2.3"],
+                            ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                            ["thickness1.1"],
+                            ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                            ["rotation1.1","rotation1.2"],
+                            ["rotation2.1"],
+                            ["rotation2.2"],
+                            ["rotation2.3"]
+                          ],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"2.2.1",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x1.1","y1.1"],
+                              "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.2.1.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":48.0,
+                                    "height":65.0,
+                                    "thickness":1.1349206349206349,
+                                    "rotation":0.0,
+                                    "fill":"0xe64d4dff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.2.1.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":48.0,
+                                    "height":20.0,
+                                    "thickness":0.0,
+                                    "rotation":0.0,
+                                    "fill":"0x4d4d4d64",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.2.2",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"No",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x2.1"],
+                              "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.2.2.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":45.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.2.2.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.2.2.3",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":-12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"2.3",
+                        "level":2,
+                        "prefix":"B.",
+                        "x":85.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":-31.0,
+                        "delta-y":0.0,
+                        "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["A.sticky-x"],
+                        "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                        "bindings":[
+                            ["A.sticky-y1","A.sticky-y2"],
+                            ["A.distribution-x1","A.distribution-x2"],
+                            ["A.delta-x1","A.delta-x2"],
+                            ["A.distribution-y1","A.distribution-y2"],
+                            ["A.delta-y1","A.delta-y2"],
+                            ["A.x1","A.x2"],
+                            ["A.y1","A.y2"],
+                            ["A.rotation1","A.rotation2"],
+                            ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                            ["reference-y1.1","reference-y1.2"],
+                            ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                            ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                            ["y1.1","y1.2"],
+                            ["y2.1","y2.2","y2.3"],
+                            ["width1.1","width1.2"],
+                            ["width2.1","width2.2","width2.3"],
+                            ["height1.1"],
+                            ["height1.2"],
+                            ["height2.1","height2.2","height2.3"],
+                            ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                            ["fill1.1"],
+                            ["fill1.2"],
+                            ["fill2.1","fill2.2","fill2.3"],
+                            ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                            ["thickness1.1"],
+                            ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                            ["rotation1.1","rotation1.2"],
+                            ["rotation2.1"],
+                            ["rotation2.2"],
+                            ["rotation2.3"]
+                          ],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"2.3.1",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x1.1","y1.1"],
+                              "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.3.1.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":34.0,
+                                    "height":82.0,
+                                    "thickness":1.1349206349206349,
+                                    "rotation":0.0,
+                                    "fill":"0xe64d4dff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.3.1.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":34.0,
+                                    "height":37.0,
+                                    "thickness":0.0,
+                                    "rotation":0.0,
+                                    "fill":"0x4d4d4d64",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.3.2",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"No",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x2.1"],
+                              "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.3.2.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":45.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.3.2.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.3.2.3",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":-12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"2.4",
+                        "level":2,
+                        "prefix":"B.",
+                        "x":121.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":-31.0,
+                        "delta-y":0.0,
+                        "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["A.sticky-x"],
+                        "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                        "bindings":[
+                            ["A.sticky-y1","A.sticky-y2"],
+                            ["A.distribution-x1","A.distribution-x2"],
+                            ["A.delta-x1","A.delta-x2"],
+                            ["A.distribution-y1","A.distribution-y2"],
+                            ["A.delta-y1","A.delta-y2"],
+                            ["A.x1","A.x2"],
+                            ["A.y1","A.y2"],
+                            ["A.rotation1","A.rotation2"],
+                            ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                            ["reference-y1.1","reference-y1.2"],
+                            ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                            ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                            ["y1.1","y1.2"],
+                            ["y2.1","y2.2","y2.3"],
+                            ["width1.1","width1.2"],
+                            ["width2.1","width2.2","width2.3"],
+                            ["height1.1"],
+                            ["height1.2"],
+                            ["height2.1","height2.2","height2.3"],
+                            ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                            ["fill1.1"],
+                            ["fill1.2"],
+                            ["fill2.1","fill2.2","fill2.3"],
+                            ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                            ["thickness1.1"],
+                            ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                            ["rotation1.1","rotation1.2"],
+                            ["rotation2.1"],
+                            ["rotation2.2"],
+                            ["rotation2.3"]
+                          ],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"2.4.1",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x1.1","y1.1"],
+                              "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.4.1.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":38.0,
+                                    "height":80.0,
+                                    "thickness":1.1349206349206349,
+                                    "rotation":0.0,
+                                    "fill":"0xe64d4dff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.4.1.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":38.0,
+                                    "height":21.0,
+                                    "thickness":0.0,
+                                    "rotation":0.0,
+                                    "fill":"0x4d4d4d64",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.4.2",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"No",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x2.1"],
+                              "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.4.2.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":45.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.4.2.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.4.2.3",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":-12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Group",
+                        "id":"2.5",
+                        "level":2,
+                        "prefix":"B.",
+                        "x":158.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":-31.0,
+                        "delta-y":0.0,
+                        "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["A.sticky-x"],
+                        "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                        "bindings":[
+                            ["A.sticky-y1","A.sticky-y2"],
+                            ["A.distribution-x1","A.distribution-x2"],
+                            ["A.delta-x1","A.delta-x2"],
+                            ["A.distribution-y1","A.distribution-y2"],
+                            ["A.delta-y1","A.delta-y2"],
+                            ["A.x1","A.x2"],
+                            ["A.y1","A.y2"],
+                            ["A.rotation1","A.rotation2"],
+                            ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                            ["reference-y1.1","reference-y1.2"],
+                            ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                            ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                            ["y1.1","y1.2"],
+                            ["y2.1","y2.2","y2.3"],
+                            ["width1.1","width1.2"],
+                            ["width2.1","width2.2","width2.3"],
+                            ["height1.1"],
+                            ["height1.2"],
+                            ["height2.1","height2.2","height2.3"],
+                            ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                            ["fill1.1"],
+                            ["fill1.2"],
+                            ["fill2.1","fill2.2","fill2.3"],
+                            ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                            ["thickness1.1"],
+                            ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                            ["rotation1.1","rotation1.2"],
+                            ["rotation2.1"],
+                            ["rotation2.2"],
+                            ["rotation2.3"]
+                          ],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"2.5.1",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x1.1","y1.1"],
+                              "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.5.1.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":36.0,
+                                    "height":59.0,
+                                    "thickness":1.1349206349206349,
+                                    "rotation":0.0,
+                                    "fill":"0xe64d4dff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.5.1.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Bottom",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "width":36.0,
+                                    "height":24.0,
+                                    "thickness":0.0,
+                                    "rotation":0.0,
+                                    "fill":"0x4d4d4d64",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"false"
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.5.2",
+                              "level":1,
+                              "prefix":"A.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"No",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":20.0,
+                              "delta-y":0.0,
+                              "common":["x2.1"],
+                              "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "components":[
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.5.2.1",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":45.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.5.2.2",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  },
+                                  {
+                                    "type":"Rectangle",
+                                    "id":"2.5.2.3",
+                                    "level":0,
+                                    "reference-x":"Center",
+                                    "reference-y":"Center",
+                                    "x":0.0,
+                                    "y":16.0,
+                                    "width":0.0,
+                                    "height":0.0,
+                                    "thickness":0.0,
+                                    "rotation":-12.0,
+                                    "fill":"0x333333ff",
+                                    "stroke":"0x4d4d4dff",
+                                    "shape":"Rectangle",
+                                    "lock":"true"
+                                  }
+                                ]
+                            }
+                          ]
+                      }
+                    ]
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":5,
+            "prefix":"E.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":64.5,
+            "y":853.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":40.0,
+            "curve":"None",
+            "common":["D.sticky-x","D.sticky-y","D.distribution-x","D.delta-x","D.distribution-y","D.delta-y","D.x","D.curve","D.stroke","D.thickness","D.rotation","C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+            "variable":["D.y","C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":4,
+                  "prefix":"D.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":7.0,
+                  "y":13.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":15.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                  "variable":["C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","fill1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                  "components":[
+                      {
+                        "type":"Collection",
+                        "id":"1.1",
+                        "level":3,
+                        "prefix":"C.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":20.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"Spacing",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"None",
+                        "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                        "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"1.1.1",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"1.1.1.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.1.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":57.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.1.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":26.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"1.1.1.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.1.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.1.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.1.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.1.2",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":48.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"1.1.2.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.2.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.2.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":49.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"1.1.2.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.2.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.2.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.2.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.1.3",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":96.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"1.1.3.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.3.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":91.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.3.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":27.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"1.1.3.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.3.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.3.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.3.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.1.4",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":150.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"1.1.4.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.4.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":60.0,
+                                          "height":57.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.4.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":60.0,
+                                          "height":21.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"1.1.4.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.4.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.4.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.4.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.1.5",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":204.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"1.1.5.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.5.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.5.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"1.1.5.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.5.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.5.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.1.5.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Collection",
+                        "id":"1.2",
+                        "level":3,
+                        "prefix":"C.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":283.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"Spacing",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"None",
+                        "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                        "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"1.2.1",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"1.2.1.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.1.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":40.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.1.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":40.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"1.2.1.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.1.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.1.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.1.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.2.2",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":44.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"1.2.2.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.2.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":65.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.2.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":20.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"1.2.2.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.2.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.2.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.2.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.2.3",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":85.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"1.2.3.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.3.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":82.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.3.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"1.2.3.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.3.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.3.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.3.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.2.4",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":121.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"1.2.4.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.4.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":38.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.4.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":38.0,
+                                          "height":21.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"1.2.4.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.4.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.4.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.4.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"1.2.5",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":158.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"1.2.5.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.5.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":36.0,
+                                          "height":59.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.5.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":36.0,
+                                          "height":24.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"1.2.5.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.5.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.5.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"1.2.5.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":4,
+                  "prefix":"D.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":7.0,
+                  "y":144.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":15.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                  "variable":["C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","fill1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                  "components":[
+                      {
+                        "type":"Collection",
+                        "id":"2.1",
+                        "level":3,
+                        "prefix":"C.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":20.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"Spacing",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"None",
+                        "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                        "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"2.1.1",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"2.1.1.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.1.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.1.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"2.1.1.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.1.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.1.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.1.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.1.2",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":48.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"2.1.2.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.2.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.2.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":49.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"2.1.2.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.2.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.2.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.2.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.1.3",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":96.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"2.1.3.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.3.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":27.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.3.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":13.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"2.1.3.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.3.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.3.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.3.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.1.4",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":150.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"2.1.4.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.4.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":60.0,
+                                          "height":39.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.4.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":60.0,
+                                          "height":21.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"2.1.4.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.4.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.4.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.4.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.1.5",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":190.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"2.1.5.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.5.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":20.0,
+                                          "height":60.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.5.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":20.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"2.1.5.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.5.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.5.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.1.5.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Collection",
+                        "id":"2.2",
+                        "level":3,
+                        "prefix":"C.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":255.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"Spacing",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"None",
+                        "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                        "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"2.2.1",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"2.2.1.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.1.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":40.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.1.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":40.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"2.2.1.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.1.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.1.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.1.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.2.2",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":44.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"2.2.2.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.2.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":65.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.2.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":20.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"2.2.2.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.2.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.2.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.2.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.2.3",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":85.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"2.2.3.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.3.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":85.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.3.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"2.2.3.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.3.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.3.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.3.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.2.4",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":121.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"2.2.4.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.4.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":38.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.4.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":38.0,
+                                          "height":21.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"2.2.4.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.4.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.4.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.4.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"2.2.5",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":156.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"2.2.5.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.5.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":32.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.5.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":32.0,
+                                          "height":24.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"2.2.5.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.5.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.5.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"2.2.5.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":4,
+                  "prefix":"D.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":7.0,
+                  "y":269.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":15.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                  "variable":["C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","fill1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                  "components":[
+                      {
+                        "type":"Collection",
+                        "id":"3.1",
+                        "level":3,
+                        "prefix":"C.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":20.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"Spacing",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"None",
+                        "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                        "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"3.1.1",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"3.1.1.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.1.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":56.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.1.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"3.1.1.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.1.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.1.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.1.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"3.1.2",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":39.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"3.1.2.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.2.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":30.0,
+                                          "height":65.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.2.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":30.0,
+                                          "height":49.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"3.1.2.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.2.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.2.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.2.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"3.1.3",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":71.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"3.1.3.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.3.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":60.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.3.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"3.1.3.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.3.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.3.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.3.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"3.1.4",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":118.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"3.1.4.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.4.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":60.0,
+                                          "height":57.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.4.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":60.0,
+                                          "height":21.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"3.1.4.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.4.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.4.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.4.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"3.1.5",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":181.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"3.1.5.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.5.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":66.0,
+                                          "height":48.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.5.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":66.0,
+                                          "height":11.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"3.1.5.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.5.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.5.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.1.5.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Collection",
+                        "id":"3.2",
+                        "level":3,
+                        "prefix":"C.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":269.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"Spacing",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"None",
+                        "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                        "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"3.2.1",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"3.2.1.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.1.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":40.0,
+                                          "height":52.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.1.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":40.0,
+                                          "height":24.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"3.2.1.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.1.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.1.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.1.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"3.2.2",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":44.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"3.2.2.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.2.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":65.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.2.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":20.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"3.2.2.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.2.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.2.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.2.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"3.2.3",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":85.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"3.2.3.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.3.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":76.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.3.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"3.2.3.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.3.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.3.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.3.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"3.2.4",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":121.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"3.2.4.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.4.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":38.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.4.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":38.0,
+                                          "height":21.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"3.2.4.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.4.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.4.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.4.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"3.2.5",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":155.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"3.2.5.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.5.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":30.0,
+                                          "height":48.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.5.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":30.0,
+                                          "height":24.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"3.2.5.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.5.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.5.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"3.2.5.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":4,
+                  "prefix":"D.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":7.0,
+                  "y":389.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":15.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.curve","C.stroke","C.thickness","C.rotation","B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                  "variable":["C.x","B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","fill1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                  "components":[
+                      {
+                        "type":"Collection",
+                        "id":"4.1",
+                        "level":3,
+                        "prefix":"C.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":20.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"Spacing",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"None",
+                        "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                        "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"4.1.1",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"4.1.1.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.1.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.1.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"4.1.1.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.1.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.1.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.1.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"4.1.2",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":41.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"4.1.2.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.2.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":58.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.2.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":18.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"4.1.2.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.2.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.2.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.2.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"4.1.3",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":82.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"4.1.3.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.3.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":61.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.3.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"4.1.3.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.3.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.3.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.3.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"4.1.4",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":136.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"4.1.4.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.4.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":60.0,
+                                          "height":57.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.4.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":60.0,
+                                          "height":21.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"4.1.4.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.4.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.4.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.4.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"4.1.5",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":189.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"4.1.5.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.5.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":46.0,
+                                          "height":80.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xb3e6b3ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.5.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":46.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"4.1.5.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.5.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.5.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.1.5.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Collection",
+                        "id":"4.2",
+                        "level":3,
+                        "prefix":"C.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":267.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"Spacing",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"None",
+                        "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.y","B.rotation","A.sticky-x1","A.sticky-y1","A.distribution-x1","A.delta-x1","A.distribution-y1","A.delta-y1","A.x1","A.y1","A.rotation1","A.sticky-x2","reference-x1.1","reference-y1.1","x1.1","y1.1","shape1.1","fill1.1","stroke1.1","thickness1.1","rotation1.1","fill1.2","thickness1.2","reference-y2.1","y2.1","fill2.1","rotation2.1","rotation2.2","rotation2.3"],
+                        "variable":["B.x","A.sticky-y2","A.distribution-x2","A.delta-x2","A.distribution-y2","A.delta-y2","A.x2","A.y2","A.rotation2","width1.1","height1.1","reference-x1.2","reference-y1.2","x1.2","y1.2","width1.2","height1.2","shape1.2","stroke1.2","rotation1.2","reference-x2.1","x2.1","width2.1","height2.1","shape2.1","stroke2.1","thickness2.1","reference-x2.2","reference-y2.2","x2.2","y2.2","width2.2","height2.2","shape2.2","fill2.2","stroke2.2","thickness2.2","reference-x2.3","reference-y2.3","x2.3","y2.3","width2.3","height2.3","shape2.3","fill2.3","stroke2.3","thickness2.3"],
+                        "components":[
+                            {
+                              "type":"Group",
+                              "id":"4.2.1",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":0.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"4.2.1.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.1.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":40.0,
+                                          "height":63.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.1.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":40.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"4.2.1.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.1.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.1.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.1.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"4.2.2",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":44.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"4.2.2.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.2.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":65.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.2.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":48.0,
+                                          "height":20.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"4.2.2.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.2.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.2.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.2.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"4.2.3",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":85.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"4.2.3.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.3.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":52.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.3.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":34.0,
+                                          "height":37.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"4.2.3.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.3.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.3.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.3.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"4.2.4",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":121.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"4.2.4.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.4.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":38.0,
+                                          "height":45.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.4.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":38.0,
+                                          "height":21.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"4.2.4.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.4.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.4.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.4.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":14.0,
+                                          "height":14.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            },
+                            {
+                              "type":"Group",
+                              "id":"4.2.5",
+                              "level":2,
+                              "prefix":"B.",
+                              "x":158.0,
+                              "y":0.0,
+                              "sticky-y":"Yes",
+                              "sticky-x":"Yes",
+                              "distribution-x":"None",
+                              "distribution-y":"None",
+                              "rotation":0.0,
+                              "delta-x":-31.0,
+                              "delta-y":0.0,
+                              "common":["A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x1","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                              "variable":["A.sticky-x"],
+                              "public":["B.x","B.y","width1.1","width1.2","width2.1","width2.2","width2.3","height1.1","height1.2","fill1.1"],
+                              "bindings":[
+                                  ["A.sticky-y1","A.sticky-y2"],
+                                  ["A.distribution-x1","A.distribution-x2"],
+                                  ["A.delta-x1","A.delta-x2"],
+                                  ["A.distribution-y1","A.distribution-y2"],
+                                  ["A.delta-y1","A.delta-y2"],
+                                  ["A.x1","A.x2"],
+                                  ["A.y1","A.y2"],
+                                  ["A.rotation1","A.rotation2"],
+                                  ["reference-x1.1","reference-x1.2","reference-x2.1","reference-x2.2","reference-x2.3"],
+                                  ["reference-y1.1","reference-y1.2"],
+                                  ["reference-y2.1","reference-y2.2","reference-y2.3"],
+                                  ["x1.1","x1.2","x2.1","x2.2","x2.3"],
+                                  ["y1.1","y1.2"],
+                                  ["y2.1","y2.2","y2.3"],
+                                  ["width1.1","width1.2"],
+                                  ["width2.1","width2.2","width2.3"],
+                                  ["height1.1"],
+                                  ["height1.2"],
+                                  ["height2.1","height2.2","height2.3"],
+                                  ["shape1.1","shape1.2","shape2.1","shape2.2","shape2.3"],
+                                  ["fill1.1"],
+                                  ["fill1.2"],
+                                  ["fill2.1","fill2.2","fill2.3"],
+                                  ["stroke1.1","stroke1.2","stroke2.1","stroke2.2","stroke2.3"],
+                                  ["thickness1.1"],
+                                  ["thickness1.2","thickness2.1","thickness2.2","thickness2.3"],
+                                  ["rotation1.1","rotation1.2"],
+                                  ["rotation2.1"],
+                                  ["rotation2.2"],
+                                  ["rotation2.3"]
+                                ],
+                              "components":[
+                                  {
+                                    "type":"Group",
+                                    "id":"4.2.5.1",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"Yes",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x1.1","y1.1"],
+                                    "variable":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.5.1.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":36.0,
+                                          "height":66.0,
+                                          "thickness":1.1349206349206349,
+                                          "rotation":0.0,
+                                          "fill":"0xe64d4dff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.5.1.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Bottom",
+                                          "x":0.0,
+                                          "y":0.0,
+                                          "width":36.0,
+                                          "height":13.0,
+                                          "thickness":0.0,
+                                          "rotation":0.0,
+                                          "fill":"0x4d4d4d64",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"false"
+                                        }
+                                      ]
+                                  },
+                                  {
+                                    "type":"Group",
+                                    "id":"4.2.5.2",
+                                    "level":1,
+                                    "prefix":"A.",
+                                    "x":0.0,
+                                    "y":0.0,
+                                    "sticky-y":"Yes",
+                                    "sticky-x":"No",
+                                    "distribution-x":"None",
+                                    "distribution-y":"None",
+                                    "rotation":0.0,
+                                    "delta-x":20.0,
+                                    "delta-y":0.0,
+                                    "common":["x2.1"],
+                                    "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                    "components":[
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.5.2.1",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":45.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.5.2.2",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        },
+                                        {
+                                          "type":"Rectangle",
+                                          "id":"4.2.5.2.3",
+                                          "level":0,
+                                          "reference-x":"Center",
+                                          "reference-y":"Center",
+                                          "x":0.0,
+                                          "y":16.0,
+                                          "width":0.0,
+                                          "height":0.0,
+                                          "thickness":0.0,
+                                          "rotation":-12.0,
+                                          "fill":"0x333333ff",
+                                          "stroke":"0x4d4d4dff",
+                                          "shape":"Rectangle",
+                                          "lock":"true"
+                                        }
+                                      ]
+                                  }
+                                ]
+                            }
+                          ]
+                      }
+                    ]
+                }
+              ]
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Column",
+            "row":1,
+            "column":0,
+            "nrows":40,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["D.y"],
+            "variables":[
+                {
+                  "name":"D.y",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Year"],
+                  "mappings":[
+                      {
+                        "from":"13.0",
+                        "to":"2017"
+                      },
+                      {
+                        "from":"144.0",
+                        "to":"2018"
+                      },
+                      {
+                        "from":"269.0",
+                        "to":"2019"
+                      },
+                      {
+                        "from":"389.0",
+                        "to":"2020"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":1,
+            "nrows":40,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["height1.1"],
+            "variables":[
+                {
+                  "name":"height1.1",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Ratings"],
+                  "function":"height1.1"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":2,
+            "nrows":40,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["width1.1"],
+            "variables":[
+                {
+                  "name":"width1.1",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Age"],
+                  "function":"width1.1"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":3,
+            "nrows":40,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["width2.1"],
+            "variables":[
+                {
+                  "name":"width2.1",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Best Seller"],
+                  "mappings":[
+                      {
+                        "from":"0.0",
+                        "to":"No"
+                      },
+                      {
+                        "from":"14.0",
+                        "to":"Yes"
+                      },
+                      {
+                        "from":"16.0",
+                        "to":"Yes"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":4,
+            "nrows":40,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["fill1.1"],
+            "variables":[
+                {
+                  "name":"fill1.1",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":true,
+                  "node":false,
+                  "labels":["Gender"],
+                  "mappings":[
+                      {
+                        "from":"0xb3e6b3ff",
+                        "to":"Fiction"
+                      },
+                      {
+                        "from":"0xe64d4dff",
+                        "to":"Non-Fiction"
+                      }
+                    ]
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/bubblechart.json b/gallery/bubblechart.json
new file mode 100644
index 0000000000000000000000000000000000000000..0ead99d359ac2a221b1771d7b526f339f458410a
--- /dev/null
+++ b/gallery/bubblechart.json
@@ -0,0 +1,375 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":191.0,
+        "y":1053.0,
+        "sticky-y":"Yes",
+        "sticky-x":"Yes",
+        "distribution-x":"None",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":10.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","width","height","shape","stroke","thickness","rotation"],
+        "variable":["x","y","fill"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y","width","height"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":24.0,
+                    "y":21.0,
+                    "width":16.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc99cc6f",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":66.0,
+                    "y":46.0,
+                    "width":16.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc99cc6f",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":109.0,
+                    "y":34.0,
+                    "width":16.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc99cc6f",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":135.0,
+                    "y":95.0,
+                    "width":16.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc99cc6f",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":75.0,
+                    "y":87.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc99cc6f",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":140.0,
+                    "y":144.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc99cc6f",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":226.0,
+                    "y":45.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc99cc6f",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":191.0,
+                    "y":118.0,
+                    "width":48.0,
+                    "height":48.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc99cc6f",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":276.0,
+                    "y":141.0,
+                    "width":48.0,
+                    "height":48.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc99cc6f",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y","width","height"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":24.0,
+                    "y":46.0,
+                    "width":16.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ff80",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":89.0,
+                    "y":59.0,
+                    "width":16.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ff80",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":84.0,
+                    "y":35.0,
+                    "width":16.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ff80",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":111.0,
+                    "y":105.0,
+                    "width":16.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ff80",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":172.0,
+                    "y":43.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ff80",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":139.0,
+                    "y":63.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ff80",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":246.0,
+                    "y":76.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ff80",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":336.0,
+                    "y":88.0,
+                    "width":48.0,
+                    "height":48.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ff80",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":344.0,
+                    "y":181.0,
+                    "width":48.0,
+                    "height":48.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x8099ff80",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/bubblechart.wrk b/gallery/bubblechart.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..06c4b3dbc3f10a29c47732ca90854338c3aecd76
--- /dev/null
+++ b/gallery/bubblechart.wrk
@@ -0,0 +1,1718 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":96.875,
+            "y":785.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":143.75,
+            "y":808.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Distance",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":44.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.y","x","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":44.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":88.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":132.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":176.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":122.0,
+            "y":908.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":29.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+            "variable":["x","height","fill"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":15.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":85.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xccccccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":44.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":129.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x808080ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":73.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":42.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e64dff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":102.0,
+                  "y":0.0,
+                  "width":28.0,
+                  "height":68.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x80b380ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":494.0,
+            "y":913.0,
+            "sticky-y":"Yes",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["y","width"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2","reference-x3"],
+                ["reference-y1"],
+                ["reference-y2","reference-y3"],
+                ["x1","x2","x3"],
+                ["height1","height3"],
+                ["height2"],
+                ["shape1","shape2","shape3"],
+                ["fill1","fill3"],
+                ["fill2"],
+                ["stroke1","stroke2","stroke3"],
+                ["thickness1","thickness2","thickness3"],
+                ["rotation1","rotation2","rotation3"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Top",
+                  "x":0.0,
+                  "y":-41.0,
+                  "width":92.0,
+                  "height":10.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e699ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":2.0,
+                  "width":13.0,
+                  "height":86.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffe6ccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":50.0,
+                  "width":55.0,
+                  "height":10.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e699ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0x808080ff",
+            "x":136.0,
+            "y":972.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["x","y","height"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":20.0,
+                  "y":133.0,
+                  "width":25.0,
+                  "height":162.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":106.0,
+                  "y":80.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":193.0,
+                  "y":206.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":281.0,
+                  "y":135.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":277.0,
+                  "y":34.0,
+                  "width":25.0,
+                  "height":49.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ],
+            "fill":"0xcce6ffff",
+            "opacity":0.3015873015873016,
+            "coloring":"Source",
+            "connections":[
+                {
+                  "origin":"3",
+                  "destination":"4",
+                  "weight":81.0
+                },
+                {
+                  "origin":"2",
+                  "destination":"5",
+                  "weight":49.0
+                },
+                {
+                  "origin":"1",
+                  "destination":"3",
+                  "weight":81.0
+                },
+                {
+                  "origin":"1",
+                  "destination":"2",
+                  "weight":81.0
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":180.0,
+            "y":1059.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":6.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":44.0,
+                  "height":95.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x80b380ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":101.0,
+                  "width":73.0,
+                  "height":20.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"your text",
+                  "fontsize":14.0,
+                  "lock":"false"
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":191.0,
+            "y":1053.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","width","height","shape","stroke","thickness","rotation"],
+            "variable":["x","y","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":24.0,
+                        "y":21.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc99cc6f",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":66.0,
+                        "y":46.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc99cc6f",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":109.0,
+                        "y":34.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc99cc6f",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":135.0,
+                        "y":95.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc99cc6f",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":75.0,
+                        "y":87.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc99cc6f",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":140.0,
+                        "y":144.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc99cc6f",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":226.0,
+                        "y":45.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc99cc6f",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":191.0,
+                        "y":118.0,
+                        "width":48.0,
+                        "height":48.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc99cc6f",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":276.0,
+                        "y":141.0,
+                        "width":48.0,
+                        "height":48.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc99cc6f",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":24.0,
+                        "y":46.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ff80",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":89.0,
+                        "y":59.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ff80",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":84.0,
+                        "y":35.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ff80",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":111.0,
+                        "y":105.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ff80",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":172.0,
+                        "y":43.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ff80",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":139.0,
+                        "y":63.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ff80",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":246.0,
+                        "y":76.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ff80",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":336.0,
+                        "y":88.0,
+                        "width":48.0,
+                        "height":48.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ff80",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":344.0,
+                        "y":181.0,
+                        "width":48.0,
+                        "height":48.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ff80",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Table",
+            "row":4,
+            "column":0,
+            "nrows":18,
+            "ncolumns":7,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["A.id","id","x","y","width","height","fill"],
+            "variables":[
+                {
+                  "name":"A.id",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["A.id"],
+                  "function":"A.id"
+                },
+                {
+                  "name":"fill",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":true,
+                  "node":false,
+                  "labels":["Sex"],
+                  "mappings":[
+                      {
+                        "from":"0x8099ff80",
+                        "to":"Male"
+                      },
+                      {
+                        "from":"0xcc99cc6f",
+                        "to":"Female"
+                      }
+                    ]
+                },
+                {
+                  "name":"height",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":true,
+                  "node":false,
+                  "labels":["Age"],
+                  "mappings":[
+                      {
+                        "from":"16.0",
+                        "to":"14"
+                      },
+                      {
+                        "from":"30.0",
+                        "to":"15"
+                      },
+                      {
+                        "from":"48.0",
+                        "to":"16"
+                      }
+                    ]
+                },
+                {
+                  "name":"id",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["id"],
+                  "function":"id"
+                },
+                {
+                  "name":"width",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["width"],
+                  "function":"width"
+                },
+                {
+                  "name":"x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Weight (kg)"],
+                  "function":"40+x/10"
+                },
+                {
+                  "name":"y",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Height (cm)"],
+                  "function":"140+y/4"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/covid-deaths.json b/gallery/covid-deaths.json
new file mode 100644
index 0000000000000000000000000000000000000000..b7d126b11f74c3015be3cbffc924ef63f28a6d33
--- /dev/null
+++ b/gallery/covid-deaths.json
@@ -0,0 +1,3737 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0x808080ff",
+        "x":68.5,
+        "y":908.0,
+        "sticky-y":"Yes",
+        "sticky-x":"Yes",
+        "distribution-x":"None",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.thickness","A.rotation","reference-x","reference-y","x","width","height","shape","stroke","thickness","rotation"],
+        "variable":["A.stroke","y","fill"],
+        "components":[
+            {
+              "type":"LineChart",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":4.166666666666666,
+              "stroke":"0xe6e64dff",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":32.0,
+              "delta-y":0.0,
+              "curve":"Bezier",
+              "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":27.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":59.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":91.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":123.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":155.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":187.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":219.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":251.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":283.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.10",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":315.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.11",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":347.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.12",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":379.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.13",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":411.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.14",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":443.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.15",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":475.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.16",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":507.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.17",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":539.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.18",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":571.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.19",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":603.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.20",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":635.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.21",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":667.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.22",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":699.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.23",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":731.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.24",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":763.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.25",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":795.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.26",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":827.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6e64dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":4.166666666666666,
+              "stroke":"0xb3e6b3ff",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":32.0,
+              "delta-y":0.0,
+              "curve":"Bezier",
+              "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":27.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":59.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":91.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":123.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":155.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":187.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":219.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":251.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":283.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.10",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":315.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.11",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":347.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.12",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":379.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.13",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":411.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.14",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":443.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.15",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":475.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.16",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":507.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.17",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":539.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.18",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":571.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.19",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":603.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.20",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":635.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.21",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":667.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.22",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":699.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.23",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":731.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.24",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":763.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.25",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":795.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.26",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":827.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3e6b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "thickness":4.166666666666666,
+              "stroke":"0xffb3b3ff",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":32.0,
+              "delta-y":0.0,
+              "curve":"Bezier",
+              "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":27.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":59.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":91.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":123.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":155.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":187.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":219.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":251.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":283.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.10",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":315.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.11",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":347.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.12",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":379.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.13",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":411.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.14",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":443.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.15",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":475.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.16",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":507.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.17",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":539.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.18",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":571.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.19",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":603.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.20",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":635.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.21",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":667.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.22",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":699.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.23",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":731.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.24",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":763.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.25",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":795.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.26",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":827.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xffb3b3ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "thickness":4.166666666666666,
+              "stroke":"0x4d66ccff",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":32.0,
+              "delta-y":0.0,
+              "curve":"Bezier",
+              "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":27.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":59.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":91.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":123.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":155.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":187.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":219.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":251.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":283.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.10",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":315.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.11",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":347.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.12",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":379.0,
+                    "y":80.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.13",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":411.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.14",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":443.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.15",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":475.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.16",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":507.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.17",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":539.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.18",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":571.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.19",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":603.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.20",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":635.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.21",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":667.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.22",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":699.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.23",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":731.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.24",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":763.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.25",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":795.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.26",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":827.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"5",
+              "level":1,
+              "prefix":"A.",
+              "thickness":4.166666666666666,
+              "stroke":"0xcc3333ff",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":32.0,
+              "delta-y":0.0,
+              "curve":"Bezier",
+              "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"5.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":27.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":59.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":91.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":123.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":155.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":187.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":219.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":251.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":283.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.10",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":315.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.11",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":347.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.12",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":379.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.13",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":411.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.14",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":443.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.15",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":475.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.16",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":507.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.17",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":539.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.18",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":571.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.19",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":603.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.20",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":635.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.21",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":667.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.22",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":699.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.23",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":731.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.24",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":763.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.25",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":795.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.26",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":827.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"6",
+              "level":1,
+              "prefix":"A.",
+              "thickness":4.166666666666666,
+              "stroke":"0xe6804dff",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":32.0,
+              "delta-y":0.0,
+              "curve":"Bezier",
+              "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"6.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":27.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":59.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":91.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":123.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":155.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":187.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":219.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":251.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":283.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.10",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":315.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.11",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":347.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.12",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":379.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.13",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":411.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.14",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":443.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.15",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":475.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.16",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":507.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.17",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":539.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.18",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":571.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.19",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":603.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.20",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":635.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.21",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":667.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.22",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":699.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.23",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":731.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.24",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":763.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.25",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":795.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.26",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":827.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe6804dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"7",
+              "level":1,
+              "prefix":"A.",
+              "thickness":4.166666666666666,
+              "stroke":"0x996699ff",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":32.0,
+              "delta-y":0.0,
+              "curve":"Bezier",
+              "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"7.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":27.0,
+                    "y":40.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":59.0,
+                    "y":120.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":91.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":123.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":155.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":187.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":219.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":251.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":283.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.10",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":315.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.11",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":347.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.12",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":379.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.13",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":411.0,
+                    "y":160.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.14",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":443.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.15",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":475.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.16",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":507.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.17",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":539.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.18",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":571.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.19",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":603.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.20",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":635.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.21",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":667.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.22",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":699.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.23",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":731.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.24",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":763.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.25",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":795.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"7.26",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":827.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x996699ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"8",
+              "level":1,
+              "prefix":"A.",
+              "thickness":4.166666666666666,
+              "stroke":"0x80801aff",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":32.0,
+              "delta-y":0.0,
+              "curve":"Bezier",
+              "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"8.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":27.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":59.0,
+                    "y":200.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":91.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":123.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":155.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":187.0,
+                    "y":240.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":219.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":251.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":283.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.10",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":315.0,
+                    "y":280.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.11",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":347.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.12",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":379.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.13",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":411.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.14",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":443.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.15",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":475.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.16",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":507.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.17",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":539.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.18",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":571.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.19",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":603.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.20",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":635.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.21",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":667.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.22",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":699.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.23",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":731.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.24",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":763.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.25",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":795.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"8.26",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":827.0,
+                    "y":320.0,
+                    "width":12.0,
+                    "height":12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x80801aff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/covid-deaths.wrk b/gallery/covid-deaths.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..af0d285173f6e5856a7a7239b8f9a00fa64d4ea4
--- /dev/null
+++ b/gallery/covid-deaths.wrk
@@ -0,0 +1,4015 @@
+{
+  "workspace":    {
+      "library":[],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0x808080ff",
+            "x":68.5,
+            "y":908.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.thickness","A.rotation","reference-x","reference-y","x","width","height","shape","stroke","thickness","rotation"],
+            "variable":["A.stroke","y","fill"],
+            "components":[
+                {
+                  "type":"LineChart",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":4.166666666666666,
+                  "stroke":"0xe6e64dff",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":32.0,
+                  "delta-y":0.0,
+                  "curve":"Bezier",
+                  "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":27.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":59.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":91.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":123.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":155.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":187.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":219.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":251.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":283.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.10",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":315.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.11",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":347.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.12",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":379.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.13",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":411.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.14",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":443.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.15",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":475.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.16",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":507.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.17",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":539.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.18",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":571.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.19",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":603.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.20",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":635.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.21",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":667.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.22",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":699.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.23",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":731.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.24",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":763.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.25",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":795.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.26",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":827.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6e64dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":4.166666666666666,
+                  "stroke":"0xb3e6b3ff",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":32.0,
+                  "delta-y":0.0,
+                  "curve":"Bezier",
+                  "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":27.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":59.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":91.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":123.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":155.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":187.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":219.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":251.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":283.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.10",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":315.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.11",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":347.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.12",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":379.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.13",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":411.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.14",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":443.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.15",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":475.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.16",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":507.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.17",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":539.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.18",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":571.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.19",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":603.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.20",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":635.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.21",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":667.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.22",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":699.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.23",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":731.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.24",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":763.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.25",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":795.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.26",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":827.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xb3e6b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":4.166666666666666,
+                  "stroke":"0xffb3b3ff",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":32.0,
+                  "delta-y":0.0,
+                  "curve":"Bezier",
+                  "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":27.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":59.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":91.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":123.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":155.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":187.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":219.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":251.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":283.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.10",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":315.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.11",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":347.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.12",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":379.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.13",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":411.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.14",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":443.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.15",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":475.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.16",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":507.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.17",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":539.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.18",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":571.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.19",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":603.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.20",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":635.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.21",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":667.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.22",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":699.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.23",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":731.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.24",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":763.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.25",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":795.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.26",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":827.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xffb3b3ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":4.166666666666666,
+                  "stroke":"0x4d66ccff",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":32.0,
+                  "delta-y":0.0,
+                  "curve":"Bezier",
+                  "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":27.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":59.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":91.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":123.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":155.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":187.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":219.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":251.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":283.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.10",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":315.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.11",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":347.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.12",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":379.0,
+                        "y":80.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.13",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":411.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.14",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":443.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.15",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":475.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.16",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":507.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.17",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":539.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.18",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":571.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.19",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":603.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.20",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":635.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.21",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":667.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.22",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":699.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.23",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":731.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.24",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":763.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.25",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":795.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.26",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":827.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x4d66ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":4.166666666666666,
+                  "stroke":"0xcc3333ff",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":32.0,
+                  "delta-y":0.0,
+                  "curve":"Bezier",
+                  "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":27.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":59.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":91.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":123.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":155.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":187.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":219.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":251.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":283.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.10",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":315.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.11",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":347.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.12",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":379.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.13",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":411.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.14",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":443.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.15",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":475.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.16",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":507.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.17",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":539.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.18",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":571.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.19",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":603.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.20",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":635.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.21",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":667.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.22",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":699.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.23",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":731.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.24",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":763.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.25",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":795.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.26",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":827.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"6",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":4.166666666666666,
+                  "stroke":"0xe6804dff",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":32.0,
+                  "delta-y":0.0,
+                  "curve":"Bezier",
+                  "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"6.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":27.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":59.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":91.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":123.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":155.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":187.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":219.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":251.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":283.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.10",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":315.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.11",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":347.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.12",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":379.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.13",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":411.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.14",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":443.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.15",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":475.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.16",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":507.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.17",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":539.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.18",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":571.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.19",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":603.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.20",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":635.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.21",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":667.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.22",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":699.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.23",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":731.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.24",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":763.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.25",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":795.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.26",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":827.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe6804dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"7",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":4.166666666666666,
+                  "stroke":"0x996699ff",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":32.0,
+                  "delta-y":0.0,
+                  "curve":"Bezier",
+                  "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"7.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":27.0,
+                        "y":40.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":59.0,
+                        "y":120.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":91.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":123.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":155.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":187.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":219.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":251.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":283.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.10",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":315.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.11",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":347.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.12",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":379.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.13",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":411.0,
+                        "y":160.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.14",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":443.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.15",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":475.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.16",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":507.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.17",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":539.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.18",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":571.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.19",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":603.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.20",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":635.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.21",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":667.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.22",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":699.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.23",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":731.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.24",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":763.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.25",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":795.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"7.26",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":827.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x996699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"8",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":4.166666666666666,
+                  "stroke":"0x80801aff",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":32.0,
+                  "delta-y":0.0,
+                  "curve":"Bezier",
+                  "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"8.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":27.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":59.0,
+                        "y":200.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":91.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":123.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":155.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":187.0,
+                        "y":240.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":219.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":251.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":283.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.10",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":315.0,
+                        "y":280.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.11",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":347.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.12",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":379.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.13",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":411.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.14",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":443.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.15",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":475.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.16",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":507.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.17",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":539.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.18",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":571.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.19",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":603.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.20",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":635.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.21",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":667.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.22",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":699.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.23",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":731.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.24",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":763.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.25",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":795.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"8.26",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":827.0,
+                        "y":320.0,
+                        "width":12.0,
+                        "height":12.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x80801aff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Text",
+            "level":0,
+            "reference-x":"Left",
+            "reference-y":"Bottom",
+            "x":70.0,
+            "y":1267.0,
+            "width":479.0,
+            "height":29.0,
+            "rotation":0.0,
+            "fill":"0xe6e6e6ff",
+            "text":"Country Ranking according to COVID19 Deaths",
+            "fontsize":20.0,
+            "lock":"false"
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Column",
+            "row":1,
+            "column":1,
+            "nrows":8,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":true,
+            "network":false,
+            "properties":["A.stroke"],
+            "variables":[
+                {
+                  "name":"A.stroke",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["A.stroke"],
+                  "function":"A.stroke"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":2,
+            "nrows":8,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":true,
+            "network":false,
+            "properties":["fill"],
+            "variables":[
+                {
+                  "name":"fill",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["fill"],
+                  "function":"fill"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":12,
+            "column":1,
+            "nrows":208,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["A.stroke"],
+            "variables":[
+                {
+                  "name":"A.stroke",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Country"],
+                  "mappings":[
+                      {
+                        "from":"0x4d66ccff",
+                        "to":"Iran"
+                      },
+                      {
+                        "from":"0x80801aff",
+                        "to":"USA"
+                      },
+                      {
+                        "from":"0x996699ff",
+                        "to":"UK"
+                      },
+                      {
+                        "from":"0xb3e6b3ff",
+                        "to":"France"
+                      },
+                      {
+                        "from":"0xcc3333ff",
+                        "to":"Italy"
+                      },
+                      {
+                        "from":"0xe6804dff",
+                        "to":"Spain"
+                      },
+                      {
+                        "from":"0xe6e64dff",
+                        "to":"Belgium"
+                      },
+                      {
+                        "from":"0xffb3b3ff",
+                        "to":"Germany"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":12,
+            "column":2,
+            "nrows":208,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["x"],
+            "variables":[
+                {
+                  "name":"x",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Date"],
+                  "mappings":[
+                      {
+                        "from":"27.0",
+                        "to":"26/3"
+                      },
+                      {
+                        "from":"59.0",
+                        "to":"27/3"
+                      },
+                      {
+                        "from":"91.0",
+                        "to":"28/3"
+                      },
+                      {
+                        "from":"123.0",
+                        "to":"29/3"
+                      },
+                      {
+                        "from":"155.0",
+                        "to":"30/3"
+                      },
+                      {
+                        "from":"187.0",
+                        "to":"31/3"
+                      },
+                      {
+                        "from":"219.0",
+                        "to":"1/4"
+                      },
+                      {
+                        "from":"251.0",
+                        "to":"2/4"
+                      },
+                      {
+                        "from":"283.0",
+                        "to":"3/4"
+                      },
+                      {
+                        "from":"315.0",
+                        "to":"4/4"
+                      },
+                      {
+                        "from":"347.0",
+                        "to":"5/4"
+                      },
+                      {
+                        "from":"379.0",
+                        "to":"6/4"
+                      },
+                      {
+                        "from":"411.0",
+                        "to":"7/4"
+                      },
+                      {
+                        "from":"443.0",
+                        "to":"8/4"
+                      },
+                      {
+                        "from":"475.0",
+                        "to":"9/4"
+                      },
+                      {
+                        "from":"507.0",
+                        "to":"10/4"
+                      },
+                      {
+                        "from":"539.0",
+                        "to":"11/4"
+                      },
+                      {
+                        "from":"571.0",
+                        "to":"12/4"
+                      },
+                      {
+                        "from":"603.0",
+                        "to":"13/4"
+                      },
+                      {
+                        "from":"635.0",
+                        "to":"14/4"
+                      },
+                      {
+                        "from":"667.0",
+                        "to":"15/4"
+                      },
+                      {
+                        "from":"699.0",
+                        "to":"16/4"
+                      },
+                      {
+                        "from":"731.0",
+                        "to":"17/4"
+                      },
+                      {
+                        "from":"763.0",
+                        "to":"18/4"
+                      },
+                      {
+                        "from":"795.0",
+                        "to":"19/4"
+                      },
+                      {
+                        "from":"827.0",
+                        "to":"20/4"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":12,
+            "column":3,
+            "nrows":208,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["y"],
+            "variables":[
+                {
+                  "name":"y",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Ranking"],
+                  "function":"9-y/40"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/custom-areachart.json b/gallery/custom-areachart.json
new file mode 100644
index 0000000000000000000000000000000000000000..25f639906c0dd7eb9e9b5d19dbec6f08de0bec0a
--- /dev/null
+++ b/gallery/custom-areachart.json
@@ -0,0 +1,341 @@
+{
+  "visualizations":[
+      {
+        "type":"AreaChart",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":53.0,
+        "y":1039.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"Distance",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":135.0,
+        "delta-y":0.0,
+        "curve":"Area",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","reference-x1","reference-y1","x1","y1","width1","height1","shape1","fontsize","fill1","stroke1","thickness1","rotation1","y2","width2","shape2","fill2","reference-x3","width3","height3","fill3"],
+        "variable":["A.x","A.y","A.rotation","reference-x2","reference-y2","x2","height2","stroke2","thickness2","rotation2","reference-y3","x3","y3","text3","rotation3"],
+        "components":[
+            {
+              "type":"Group",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "x":48.0,
+              "y":28.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":4.0,
+              "common":["reference-x","reference-y","x","stroke","thickness","rotation"],
+              "variable":["y","width","height","shape","text","fontsize","fill"],
+              "public":["A.x","A.y","A.rotation","height2","text3"],
+              "bindings":[
+                  ["reference-x1","reference-x2"],
+                  ["reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["x1","x2","x3"],
+                  ["stroke1","stroke2"],
+                  ["thickness1","thickness2"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":79.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff8080ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Triangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":24.0,
+                    "width":38.0,
+                    "height":88.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x99b3ffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Triangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":116.0,
+                    "width":64.0,
+                    "height":27.0,
+                    "rotation":0.0,
+                    "fill":"0x696969ff",
+                    "text":"Paul",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "x":183.0,
+              "y":100.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":336.0,
+              "delta-x":0.0,
+              "delta-y":4.0,
+              "common":["reference-x","reference-y","x","stroke","thickness","rotation"],
+              "variable":["y","width","height","shape","text","fontsize","fill"],
+              "public":["A.x","A.y","A.rotation","height2","text3"],
+              "bindings":[
+                  ["reference-x1","reference-x2"],
+                  ["reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["x1","x2","x3"],
+                  ["stroke1","stroke2"],
+                  ["thickness1","thickness2"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":79.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff8080ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Triangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":24.0,
+                    "width":38.0,
+                    "height":66.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x99b3ffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Triangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":94.0,
+                    "width":64.0,
+                    "height":27.0,
+                    "rotation":0.0,
+                    "fill":"0x696969ff",
+                    "text":"Eloïse",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "x":318.0,
+              "y":109.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":15.0,
+              "delta-x":0.0,
+              "delta-y":4.0,
+              "common":["reference-x","reference-y","x","stroke","thickness","rotation"],
+              "variable":["y","width","height","shape","text","fontsize","fill"],
+              "public":["A.x","A.y","A.rotation","height2","text3"],
+              "bindings":[
+                  ["reference-x1","reference-x2"],
+                  ["reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["x1","x2","x3"],
+                  ["stroke1","stroke2"],
+                  ["thickness1","thickness2"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":79.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff8080ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Triangle",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":24.0,
+                    "width":38.0,
+                    "height":88.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x99b3ffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Triangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"3.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":116.0,
+                    "width":64.0,
+                    "height":27.0,
+                    "rotation":0.0,
+                    "fill":"0x696969ff",
+                    "text":"Daniel",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "x":453.0,
+              "y":162.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":33.0,
+              "delta-x":0.0,
+              "delta-y":4.0,
+              "common":["reference-x","reference-y","x","stroke","thickness","rotation"],
+              "variable":["y","width","height","shape","text","fontsize","fill"],
+              "public":["A.x","A.y","A.rotation","height2","text3"],
+              "bindings":[
+                  ["reference-x1","reference-x2"],
+                  ["reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["x1","x2","x3"],
+                  ["stroke1","stroke2"],
+                  ["thickness1","thickness2"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":79.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff8080ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Triangle",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":24.0,
+                    "width":38.0,
+                    "height":50.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x99b3ffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Triangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"4.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":78.0,
+                    "width":64.0,
+                    "height":27.0,
+                    "rotation":0.0,
+                    "fill":"0x696969ff",
+                    "text":"Eloïse",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/custom-areachart.wrk b/gallery/custom-areachart.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..897897624657a19b78a01d55c81438b4c3f792a3
--- /dev/null
+++ b/gallery/custom-areachart.wrk
@@ -0,0 +1,1869 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":497.0,
+            "y":1167.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":490.0,
+            "y":937.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+            "variable":["x","y","width","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":125.0,
+                        "y":141.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":88.0,
+                        "y":76.0,
+                        "width":18.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":116.0,
+                        "y":36.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":206.0,
+                        "y":69.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":186.0,
+                        "y":114.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":266.0,
+                        "y":107.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":216.0,
+                        "y":141.0,
+                        "width":14.0,
+                        "height":14.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":300.0,
+                        "y":188.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":30.0,
+                        "y":56.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":67.0,
+                        "y":104.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":126.0,
+                        "y":68.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":164.0,
+                        "y":71.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":147.0,
+                        "y":116.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":257.0,
+                        "y":157.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":311.0,
+                        "y":149.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":237.0,
+                        "y":97.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0x808080ff",
+            "x":481.0,
+            "y":663.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":107.875,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+            "variable":["A.x","y","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":28.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":10.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","height"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":19.0,
+                        "height":65.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":75.0,
+                        "width":19.0,
+                        "height":75.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":160.0,
+                        "width":19.0,
+                        "height":65.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":135.875,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":10.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","height"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":19.0,
+                        "height":65.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":75.0,
+                        "width":19.0,
+                        "height":85.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":170.0,
+                        "width":19.0,
+                        "height":65.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":243.75,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":10.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","height"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":19.0,
+                        "height":65.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcccc66ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":75.0,
+                        "width":19.0,
+                        "height":65.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcccc66ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":150.0,
+                        "width":19.0,
+                        "height":75.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcccc66ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ],
+            "fill":"0xaaaabcff",
+            "opacity":0.5,
+            "coloring":"Destination",
+            "connections":[
+                {
+                  "origin":"2.2",
+                  "destination":"3.1",
+                  "weight":10.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.2",
+                  "weight":10.0
+                },
+                {
+                  "origin":"2.3",
+                  "destination":"3.3",
+                  "weight":55.0
+                },
+                {
+                  "origin":"2.3",
+                  "destination":"3.2",
+                  "weight":10.0
+                },
+                {
+                  "origin":"1.2",
+                  "destination":"2.3",
+                  "weight":10.0
+                },
+                {
+                  "origin":"2.1",
+                  "destination":"3.1",
+                  "weight":55.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.1",
+                  "weight":55.0
+                },
+                {
+                  "origin":"2.2",
+                  "destination":"3.3",
+                  "weight":20.0
+                },
+                {
+                  "origin":"1.2",
+                  "destination":"2.2",
+                  "weight":55.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.3",
+                  "weight":55.0
+                },
+                {
+                  "origin":"1.2",
+                  "destination":"2.1",
+                  "weight":10.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.2",
+                  "weight":10.0
+                },
+                {
+                  "origin":"2.2",
+                  "destination":"3.2",
+                  "weight":55.0
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":1004.0,
+            "y":1228.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":66.0,
+                  "height":62.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":72.0,
+                  "width":75.0,
+                  "height":19.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"my label",
+                  "fontsize":14.0,
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":1004.0,
+            "y":935.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+            "variable":["y","width","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":-72.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":-82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":-89.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":-93.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":-51.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":-26.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":86.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":103.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":125.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":66.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":36.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":9.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":978.0,
+            "y":803.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":-124.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x1","y","stroke","thickness","rotation"],
+            "variable":["width","height","shape","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["y1","y2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":106.0,
+                  "height":106.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff9999ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":78.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"false"
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"AreaChart",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":53.0,
+            "y":1039.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":135.0,
+            "delta-y":0.0,
+            "curve":"Area",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","reference-x1","reference-y1","x1","y1","width1","height1","shape1","fontsize","fill1","stroke1","thickness1","rotation1","y2","width2","shape2","fill2","reference-x3","width3","height3","fill3"],
+            "variable":["A.x","A.y","A.rotation","reference-x2","reference-y2","x2","height2","stroke2","thickness2","rotation2","reference-y3","x3","y3","text3","rotation3"],
+            "components":[
+                {
+                  "type":"Group",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":48.0,
+                  "y":28.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":4.0,
+                  "common":["reference-x","reference-y","x","stroke","thickness","rotation"],
+                  "variable":["y","width","height","shape","text","fontsize","fill"],
+                  "public":["A.x","A.y","A.rotation","height2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2"],
+                      ["reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["stroke1","stroke2"],
+                      ["thickness1","thickness2"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":79.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff8080ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Triangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":24.0,
+                        "width":38.0,
+                        "height":88.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Triangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":116.0,
+                        "width":64.0,
+                        "height":27.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Paul",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":183.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":336.0,
+                  "delta-x":0.0,
+                  "delta-y":4.0,
+                  "common":["reference-x","reference-y","x","stroke","thickness","rotation"],
+                  "variable":["y","width","height","shape","text","fontsize","fill"],
+                  "public":["A.x","A.y","A.rotation","height2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2"],
+                      ["reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["stroke1","stroke2"],
+                      ["thickness1","thickness2"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":79.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff8080ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Triangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":24.0,
+                        "width":38.0,
+                        "height":66.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Triangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":94.0,
+                        "width":64.0,
+                        "height":27.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Eloïse",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":318.0,
+                  "y":109.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":15.0,
+                  "delta-x":0.0,
+                  "delta-y":4.0,
+                  "common":["reference-x","reference-y","x","stroke","thickness","rotation"],
+                  "variable":["y","width","height","shape","text","fontsize","fill"],
+                  "public":["A.x","A.y","A.rotation","height2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2"],
+                      ["reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["stroke1","stroke2"],
+                      ["thickness1","thickness2"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":79.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff8080ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Triangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":24.0,
+                        "width":38.0,
+                        "height":88.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Triangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":116.0,
+                        "width":64.0,
+                        "height":27.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Daniel",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":453.0,
+                  "y":162.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":33.0,
+                  "delta-x":0.0,
+                  "delta-y":4.0,
+                  "common":["reference-x","reference-y","x","stroke","thickness","rotation"],
+                  "variable":["y","width","height","shape","text","fontsize","fill"],
+                  "public":["A.x","A.y","A.rotation","height2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2"],
+                      ["reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["stroke1","stroke2"],
+                      ["thickness1","thickness2"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":79.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff8080ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Triangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":24.0,
+                        "width":38.0,
+                        "height":50.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Triangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":78.0,
+                        "width":64.0,
+                        "height":27.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Eloïse",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Table",
+            "row":5,
+            "column":0,
+            "nrows":4,
+            "ncolumns":5,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["A.id","A.x","A.y","A.rotation","height2"],
+            "variables":[
+                {
+                  "name":"A.id",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["A.id"],
+                  "function":"A.id"
+                },
+                {
+                  "name":"A.rotation",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["A.rotation"],
+                  "function":"A.rotation"
+                },
+                {
+                  "name":"A.x",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Day"],
+                  "mappings":[
+                      {
+                        "from":"48.0",
+                        "to":"Monday"
+                      },
+                      {
+                        "from":"183.0",
+                        "to":"Tuesday"
+                      },
+                      {
+                        "from":"318.0",
+                        "to":"Wednesday"
+                      },
+                      {
+                        "from":"453.0",
+                        "to":"Thursday"
+                      }
+                    ]
+                },
+                {
+                  "name":"A.y",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Points"],
+                  "function":"A.y"
+                },
+                {
+                  "name":"height2",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["height2"],
+                  "function":"height2"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":5,
+            "column":5,
+            "nrows":4,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["text3"],
+            "variables":[
+                {
+                  "name":"text3",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Leader"],
+                  "function":"text3"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/custom-sankey.json b/gallery/custom-sankey.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f85ebf91e3e5865712d2501c41bfe7c82d6257f
--- /dev/null
+++ b/gallery/custom-sankey.json
@@ -0,0 +1,378 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":132.0,
+        "y":981.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.rotation","reference-x1","reference-y1","x1","y1","width1","height1","shape1","fill1","stroke1","thickness1","rotation1","y2","height3","shape3","fill3"],
+        "variable":["A.x","A.y","reference-x2","reference-y2","x2","width2","height2","shape2","fill2","stroke2","thickness2","rotation2","reference-x3","reference-y3","x3","y3","width3","stroke3","thickness3","rotation3"],
+        "components":[
+            {
+              "type":"Group",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "x":-33.0,
+              "y":123.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":5.0,
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "public":["A.x","A.y","height2","fill2"],
+              "bindings":[
+                  ["reference-x1","reference-x2","reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["x1","x2","x3"],
+                  ["width1","width2","width3"],
+                  ["shape1","shape2"],
+                  ["shape3"],
+                  ["stroke1","stroke2","stroke3"],
+                  ["thickness1","thickness2","thickness3"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":79.0,
+                    "height":13.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x666666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":18.0,
+                    "width":79.0,
+                    "height":112.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xffe666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Triangle",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":135.0,
+                    "width":79.0,
+                    "height":31.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff8080ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Triangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "x":180.0,
+              "y":238.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":5.0,
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "public":["A.x","A.y","height2","fill2"],
+              "bindings":[
+                  ["reference-x1","reference-x2","reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["x1","x2","x3"],
+                  ["width1","width2","width3"],
+                  ["shape1","shape2"],
+                  ["shape3"],
+                  ["stroke1","stroke2","stroke3"],
+                  ["thickness1","thickness2","thickness3"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":79.0,
+                    "height":13.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x666666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":18.0,
+                    "width":79.0,
+                    "height":40.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x99cc99ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Triangle",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":63.0,
+                    "width":79.0,
+                    "height":31.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff8080ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Triangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "x":184.0,
+              "y":12.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":5.0,
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "public":["A.x","A.y","height2","fill2"],
+              "bindings":[
+                  ["reference-x1","reference-x2","reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["x1","x2","x3"],
+                  ["width1","width2","width3"],
+                  ["shape1","shape2"],
+                  ["shape3"],
+                  ["stroke1","stroke2","stroke3"],
+                  ["thickness1","thickness2","thickness3"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":79.0,
+                    "height":13.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x666666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":18.0,
+                    "width":79.0,
+                    "height":72.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xffe666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Triangle",
+                    "id":"3.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":95.0,
+                    "width":79.0,
+                    "height":31.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff8080ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Triangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "x":411.0,
+              "y":80.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":5.0,
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "public":["A.x","A.y","height2","fill2"],
+              "bindings":[
+                  ["reference-x1","reference-x2","reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["x1","x2","x3"],
+                  ["width1","width2","width3"],
+                  ["shape1","shape2"],
+                  ["shape3"],
+                  ["stroke1","stroke2","stroke3"],
+                  ["thickness1","thickness2","thickness3"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":79.0,
+                    "height":13.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x666666ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":18.0,
+                    "width":79.0,
+                    "height":112.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xb3ccffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Triangle",
+                    "id":"4.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":135.0,
+                    "width":79.0,
+                    "height":31.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff8080ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Triangle",
+                    "lock":"false"
+                  }
+                ]
+            }
+          ],
+        "fill":"0xaaaabcff",
+        "opacity":0.3412698412698413,
+        "coloring":"Destination",
+        "connections":[
+            {
+              "origin":"3.2",
+              "destination":"4.2",
+              "weight":72.0
+            },
+            {
+              "origin":"1.2",
+              "destination":"2.2",
+              "weight":40.0
+            },
+            {
+              "origin":"2.2",
+              "destination":"4.2",
+              "weight":40.0
+            },
+            {
+              "origin":"1.2",
+              "destination":"3.2",
+              "weight":72.0
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/custom-sankey.wrk b/gallery/custom-sankey.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..4a9e21858b3a65bcff1b8102343116e12ef53e39
--- /dev/null
+++ b/gallery/custom-sankey.wrk
@@ -0,0 +1,1274 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":1004.0,
+            "y":1228.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":66.0,
+                  "height":62.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":72.0,
+                  "width":75.0,
+                  "height":19.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"my label",
+                  "fontsize":14.0,
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":1004.0,
+            "y":935.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+            "variable":["y","width","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":-72.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":-82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":-89.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":-93.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":-51.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":-26.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":86.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":103.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":125.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":66.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":36.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":9.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":978.0,
+            "y":803.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":-124.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x1","y","stroke","thickness","rotation"],
+            "variable":["width","height","shape","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["y1","y2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":106.0,
+                  "height":106.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff9999ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":78.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":222.5,
+            "y":1071.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":4.0,
+            "common":["reference-x","reference-y","x","shape","stroke","thickness","rotation"],
+            "variable":["y","width","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["shape1","shape2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":88.0,
+                  "height":12.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffccccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":16.0,
+                  "width":16.0,
+                  "height":91.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3ccffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":98.0,
+            "y":903.5,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":23.0,
+                  "y":14.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":16.0,
+                        "height":44.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xccccccff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":51.0,
+                        "width":16.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe666ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":68.0,
+                        "width":16.0,
+                        "height":148.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":223.0,
+                        "width":16.0,
+                        "height":96.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":406.0,
+                  "y":14.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":16.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xccccccff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":49.0,
+                        "width":16.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe666ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":74.0,
+                        "width":16.0,
+                        "height":146.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":227.0,
+                        "width":16.0,
+                        "height":92.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ],
+            "fill":"0xaaaabcff",
+            "opacity":0.3253968253968254,
+            "coloring":"Source",
+            "connections":[
+                {
+                  "origin":"1.4",
+                  "destination":"2.3",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.3",
+                  "weight":138.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.4",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.4",
+                  "weight":84.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.2",
+                  "weight":6.3953488372093
+                },
+                {
+                  "origin":"1.2",
+                  "destination":"2.2",
+                  "weight":10.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.3",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.1",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.1",
+                  "weight":30.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.4",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.1",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.2",
+                  "weight":2.0
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":204.0,
+            "y":990.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":5.0,
+            "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+            "variable":["y","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2","reference-x3"],
+                ["reference-y1","reference-y2","reference-y3"],
+                ["x1","x2","x3"],
+                ["width1","width2","width3"],
+                ["shape1","shape2"],
+                ["shape3"],
+                ["stroke1","stroke2","stroke3"],
+                ["thickness1","thickness2","thickness3"],
+                ["rotation1","rotation2","rotation3"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":83.0,
+                  "height":13.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x666666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":18.0,
+                  "width":83.0,
+                  "height":72.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffe666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Triangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":95.0,
+                  "width":83.0,
+                  "height":31.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff8080ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Triangle",
+                  "lock":"false"
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":132.0,
+            "y":981.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.rotation","reference-x1","reference-y1","x1","y1","width1","height1","shape1","fill1","stroke1","thickness1","rotation1","y2","height3","shape3","fill3"],
+            "variable":["A.x","A.y","reference-x2","reference-y2","x2","width2","height2","shape2","fill2","stroke2","thickness2","rotation2","reference-x3","reference-y3","x3","y3","width3","stroke3","thickness3","rotation3"],
+            "components":[
+                {
+                  "type":"Group",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":-33.0,
+                  "y":123.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "public":["A.x","A.y","height2","fill2"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["width1","width2","width3"],
+                      ["shape1","shape2"],
+                      ["shape3"],
+                      ["stroke1","stroke2","stroke3"],
+                      ["thickness1","thickness2","thickness3"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":79.0,
+                        "height":13.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x666666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":18.0,
+                        "width":79.0,
+                        "height":112.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Triangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":135.0,
+                        "width":79.0,
+                        "height":31.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff8080ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Triangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":180.0,
+                  "y":238.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "public":["A.x","A.y","height2","fill2"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["width1","width2","width3"],
+                      ["shape1","shape2"],
+                      ["shape3"],
+                      ["stroke1","stroke2","stroke3"],
+                      ["thickness1","thickness2","thickness3"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":79.0,
+                        "height":13.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x666666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":18.0,
+                        "width":79.0,
+                        "height":40.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99cc99ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Triangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":63.0,
+                        "width":79.0,
+                        "height":31.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff8080ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Triangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":184.0,
+                  "y":12.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "public":["A.x","A.y","height2","fill2"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["width1","width2","width3"],
+                      ["shape1","shape2"],
+                      ["shape3"],
+                      ["stroke1","stroke2","stroke3"],
+                      ["thickness1","thickness2","thickness3"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":79.0,
+                        "height":13.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x666666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":18.0,
+                        "width":79.0,
+                        "height":72.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Triangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":95.0,
+                        "width":79.0,
+                        "height":31.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff8080ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Triangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":411.0,
+                  "y":80.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "public":["A.x","A.y","height2","fill2"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["width1","width2","width3"],
+                      ["shape1","shape2"],
+                      ["shape3"],
+                      ["stroke1","stroke2","stroke3"],
+                      ["thickness1","thickness2","thickness3"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":79.0,
+                        "height":13.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x666666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":18.0,
+                        "width":79.0,
+                        "height":112.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xb3ccffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Triangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":135.0,
+                        "width":79.0,
+                        "height":31.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff8080ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Triangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ],
+            "fill":"0xaaaabcff",
+            "opacity":0.3412698412698413,
+            "coloring":"Destination",
+            "connections":[
+                {
+                  "origin":"3.2",
+                  "destination":"4.2",
+                  "weight":72.0
+                },
+                {
+                  "origin":"1.2",
+                  "destination":"2.2",
+                  "weight":40.0
+                },
+                {
+                  "origin":"2.2",
+                  "destination":"4.2",
+                  "weight":40.0
+                },
+                {
+                  "origin":"1.2",
+                  "destination":"3.2",
+                  "weight":72.0
+                }
+              ]
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Column",
+            "row":6,
+            "column":1,
+            "nrows":4,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["height2"],
+            "variables":[
+                {
+                  "name":"height2",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Budget"],
+                  "function":"100*height2"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/greece-population-pyramid.json b/gallery/greece-population-pyramid.json
new file mode 100644
index 0000000000000000000000000000000000000000..1b58e46fe792f78f5ee1f1baa34f1ac2c9fb32be
--- /dev/null
+++ b/gallery/greece-population-pyramid.json
@@ -0,0 +1,1243 @@
+{
+  "visualizations":[
+      {
+        "type":"LineChart",
+        "level":3,
+        "prefix":"C.",
+        "thickness":5.119047619047619,
+        "stroke":"0x999999ff",
+        "x":89.5,
+        "y":869.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"Distance",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":341.5,
+        "delta-y":0.0,
+        "curve":"Bezier",
+        "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.curve","B.stroke","B.thickness","B.rotation","A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","y","height","shape","fill","stroke","thickness","rotation"],
+        "variable":["B.x","B.y","width"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":2,
+              "prefix":"B.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":75.5,
+              "y":63.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+              "variable":["y","width","fill"],
+              "components":[
+                  {
+                    "type":"Collection",
+                    "id":"1.1",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":156.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":3.0,
+                    "curve":"None",
+                    "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["y","width"],
+                    "components":[
+                        {
+                          "type":"Rectangle",
+                          "id":"1.1.1",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":0.0,
+                          "width":-130.0,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.1.2",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":26.0,
+                          "width":-134.0,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.1.3",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":52.0,
+                          "width":-120.6003839616056,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.1.4",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":78.0,
+                          "width":-98.3243975988336,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.1.5",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":104.0,
+                          "width":-106.4741568986512,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.1.6",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":130.0,
+                          "width":-90.4824457002472,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.1.7",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":156.0,
+                          "width":-62.86374232842952,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.1.8",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":182.0,
+                          "width":-43.45978541642792,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.1.9",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":208.0,
+                          "width":-12.59860898930272,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.1.10",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":234.0,
+                          "width":-0.99663771211612,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        }
+                      ]
+                  },
+                  {
+                    "type":"Collection",
+                    "id":"1.2",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":156.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":3.0,
+                    "curve":"None",
+                    "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["y","width"],
+                    "components":[
+                        {
+                          "type":"Rectangle",
+                          "id":"1.2.1",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":0.0,
+                          "width":119.0,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.2.2",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":26.0,
+                          "width":120.0,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.2.3",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":52.0,
+                          "width":110.9956950309328,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.2.4",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":78.0,
+                          "width":97.7371717165488,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.2.5",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":104.0,
+                          "width":113.2469871899664,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.2.6",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":130.0,
+                          "width":91.1532320169608,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.2.7",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":156.0,
+                          "width":73.52767898728864,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.2.8",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":182.0,
+                          "width":53.31342786375032,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.2.9",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":208.0,
+                          "width":18.98586978985128,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"1.2.10",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":234.0,
+                          "width":2.04006387023608,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        }
+                      ]
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":2,
+              "prefix":"B.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":417.0,
+              "y":208.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+              "variable":["y","width","fill"],
+              "components":[
+                  {
+                    "type":"Collection",
+                    "id":"2.1",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":156.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":3.0,
+                    "curve":"None",
+                    "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["y","width"],
+                    "components":[
+                        {
+                          "type":"Rectangle",
+                          "id":"2.1.1",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":0.0,
+                          "width":-81.0,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.1.2",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":26.0,
+                          "width":-101.723079660188,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.1.3",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":52.0,
+                          "width":-130.5284446207432,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.1.4",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":78.0,
+                          "width":-127.5656618560784,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.1.5",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":104.0,
+                          "width":-111.3384716071192,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.1.6",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":130.0,
+                          "width":-88.0450444644344,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.1.7",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":156.0,
+                          "width":-84.2346734539568,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.1.8",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":182.0,
+                          "width":-55.85760488423456,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.1.9",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":208.0,
+                          "width":-17.29088735525344,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.1.10",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":234.0,
+                          "width":-2.603182268326088,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        }
+                      ]
+                  },
+                  {
+                    "type":"Collection",
+                    "id":"2.2",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":156.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":3.0,
+                    "curve":"None",
+                    "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["y","width"],
+                    "components":[
+                        {
+                          "type":"Rectangle",
+                          "id":"2.2.1",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":0.0,
+                          "width":75.0,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.2.2",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":26.0,
+                          "width":93.0238933518584,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.2.3",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":52.0,
+                          "width":119.0182296787376,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.2.4",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":78.0,
+                          "width":120.5432303605032,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.2.5",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":104.0,
+                          "width":109.5745642803936,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.2.6",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":130.0,
+                          "width":89.6731977362528,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.2.7",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":156.0,
+                          "width":95.510110933932,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.2.8",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":182.0,
+                          "width":65.95495183868432,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.2.9",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":208.0,
+                          "width":26.83355317264728,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"2.2.10",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":234.0,
+                          "width":4.556773801851816,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        }
+                      ]
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"3",
+              "level":2,
+              "prefix":"B.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":758.5,
+              "y":142.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+              "variable":["y","width","fill"],
+              "components":[
+                  {
+                    "type":"Collection",
+                    "id":"3.1",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":156.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":3.0,
+                    "curve":"None",
+                    "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["y","width"],
+                    "components":[
+                        {
+                          "type":"Rectangle",
+                          "id":"3.1.1",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":0.0,
+                          "width":-71.0,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.1.2",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":26.0,
+                          "width":-85.8144901722616,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.1.3",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":52.0,
+                          "width":-85.574294356376,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.1.4",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":78.0,
+                          "width":-107.4604179266456,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.1.5",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":104.0,
+                          "width":-124.1204059715872,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.1.6",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":130.0,
+                          "width":-115.0304955641568,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.1.7",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":156.0,
+                          "width":-92.073498981396,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.1.8",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":182.0,
+                          "width":-68.14180153898904,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.1.9",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":208.0,
+                          "width":-42.23333631753696,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.1.10",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":234.0,
+                          "width":-8.26689570755536,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0x234ae3ac",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        }
+                      ]
+                  },
+                  {
+                    "type":"Collection",
+                    "id":"3.2",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xd9cccc80",
+                    "x":156.0,
+                    "y":0.0,
+                    "sticky-y":"Yes",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":3.0,
+                    "curve":"None",
+                    "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["y","width"],
+                    "components":[
+                        {
+                          "type":"Rectangle",
+                          "id":"3.2.1",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":0.0,
+                          "width":64.0,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.2.2",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":26.0,
+                          "width":78.39720532179687,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.2.3",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":52.0,
+                          "width":76.87430166018808,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.2.4",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":78.0,
+                          "width":97.8784036116768,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.2.5",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":104.0,
+                          "width":117.6788644924,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.2.6",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":130.0,
+                          "width":116.0830037514864,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.2.7",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":156.0,
+                          "width":100.748902911688,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.2.8",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":182.0,
+                          "width":78.43353312368224,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.2.9",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":208.0,
+                          "width":58.04534568880568,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        },
+                        {
+                          "type":"Rectangle",
+                          "id":"3.2.10",
+                          "level":0,
+                          "reference-x":"Left",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":234.0,
+                          "width":11.3507046048504,
+                          "height":23.0,
+                          "thickness":0.5,
+                          "rotation":0.0,
+                          "fill":"0xde2323b1",
+                          "stroke":"0x50508000",
+                          "shape":"Rectangle",
+                          "lock":"false"
+                        }
+                      ]
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/greece-population-pyramid.wrk b/gallery/greece-population-pyramid.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..4ddb3f3d3ad0a5fdc073351c6aee1bbc3d44e091
--- /dev/null
+++ b/gallery/greece-population-pyramid.wrk
@@ -0,0 +1,2307 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":1004.0,
+            "y":1228.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":66.0,
+                  "height":62.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":72.0,
+                  "width":75.0,
+                  "height":19.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"my label",
+                  "fontsize":14.0,
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":978.0,
+            "y":803.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":-124.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x1","y","stroke","thickness","rotation"],
+            "variable":["width","height","shape","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["y1","y2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":106.0,
+                  "height":106.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff9999ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":78.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":222.5,
+            "y":1071.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":4.0,
+            "common":["reference-x","reference-y","x","shape","stroke","thickness","rotation"],
+            "variable":["y","width","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["shape1","shape2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":88.0,
+                  "height":12.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffccccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":16.0,
+                  "width":16.0,
+                  "height":91.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3ccffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":98.0,
+            "y":903.5,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":23.0,
+                  "y":14.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":16.0,
+                        "height":44.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xccccccff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":51.0,
+                        "width":16.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe666ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":68.0,
+                        "width":16.0,
+                        "height":148.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":223.0,
+                        "width":16.0,
+                        "height":96.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":406.0,
+                  "y":14.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":16.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xccccccff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":49.0,
+                        "width":16.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe666ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":74.0,
+                        "width":16.0,
+                        "height":146.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":227.0,
+                        "width":16.0,
+                        "height":92.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ],
+            "fill":"0xaaaabcff",
+            "opacity":0.3253968253968254,
+            "coloring":"Source",
+            "connections":[
+                {
+                  "origin":"1.4",
+                  "destination":"2.3",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.2",
+                  "weight":2.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.1",
+                  "weight":30.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.4",
+                  "weight":84.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.2",
+                  "weight":6.3953488372093
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.1",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.3",
+                  "weight":138.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.4",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.3",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.2",
+                  "destination":"2.2",
+                  "weight":10.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.1",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.4",
+                  "weight":4.0
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":204.0,
+            "y":990.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":5.0,
+            "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+            "variable":["y","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2","reference-x3"],
+                ["reference-y1","reference-y2","reference-y3"],
+                ["x1","x2","x3"],
+                ["width1","width2","width3"],
+                ["shape1","shape2"],
+                ["shape3"],
+                ["stroke1","stroke2","stroke3"],
+                ["thickness1","thickness2","thickness3"],
+                ["rotation1","rotation2","rotation3"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":83.0,
+                  "height":13.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x666666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":18.0,
+                  "width":83.0,
+                  "height":72.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffe666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Triangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":95.0,
+                  "width":83.0,
+                  "height":31.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff8080ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Triangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":223.0,
+            "y":1102.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+            "variable":["y","width","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":123.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":-34.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":23.0,
+                        "width":-57.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":46.0,
+                        "width":-75.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":69.0,
+                        "width":-105.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":92.0,
+                        "width":-90.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":115.0,
+                        "width":-64.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":138.0,
+                        "width":-36.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":161.0,
+                        "width":-29.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.9",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":184.0,
+                        "width":-23.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.10",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":207.0,
+                        "width":-18.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":123.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":23.0,
+                        "width":65.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":46.0,
+                        "width":126.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":69.0,
+                        "width":135.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":92.0,
+                        "width":100.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":115.0,
+                        "width":73.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":138.0,
+                        "width":48.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":161.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.9",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":184.0,
+                        "width":24.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.10",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":207.0,
+                        "width":18.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff6666ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"LineChart",
+            "level":3,
+            "prefix":"C.",
+            "thickness":5.119047619047619,
+            "stroke":"0x999999ff",
+            "x":89.5,
+            "y":869.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":341.5,
+            "delta-y":0.0,
+            "curve":"Bezier",
+            "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.curve","B.stroke","B.thickness","B.rotation","A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","y","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["B.x","B.y","width"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":2,
+                  "prefix":"B.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":75.5,
+                  "y":63.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+                  "variable":["y","width","fill"],
+                  "components":[
+                      {
+                        "type":"Collection",
+                        "id":"1.1",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":156.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"Spacing",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":3.0,
+                        "curve":"None",
+                        "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["y","width"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.1",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":-130.0,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.2",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":26.0,
+                              "width":-134.0,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.3",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":52.0,
+                              "width":-120.6003839616056,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.4",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":78.0,
+                              "width":-98.3243975988336,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.5",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":104.0,
+                              "width":-106.4741568986512,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.6",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":130.0,
+                              "width":-90.4824457002472,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.7",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":156.0,
+                              "width":-62.86374232842952,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.8",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":182.0,
+                              "width":-43.45978541642792,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.9",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":208.0,
+                              "width":-12.59860898930272,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.1.10",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":234.0,
+                              "width":-0.99663771211612,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Collection",
+                        "id":"1.2",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":156.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"Spacing",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":3.0,
+                        "curve":"None",
+                        "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["y","width"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.1",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":119.0,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.2",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":26.0,
+                              "width":120.0,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.3",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":52.0,
+                              "width":110.9956950309328,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.4",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":78.0,
+                              "width":97.7371717165488,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.5",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":104.0,
+                              "width":113.2469871899664,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.6",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":130.0,
+                              "width":91.1532320169608,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.7",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":156.0,
+                              "width":73.52767898728864,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.8",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":182.0,
+                              "width":53.31342786375032,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.9",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":208.0,
+                              "width":18.98586978985128,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"1.2.10",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":234.0,
+                              "width":2.04006387023608,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":2,
+                  "prefix":"B.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":417.0,
+                  "y":208.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+                  "variable":["y","width","fill"],
+                  "components":[
+                      {
+                        "type":"Collection",
+                        "id":"2.1",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":156.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"Spacing",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":3.0,
+                        "curve":"None",
+                        "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["y","width"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.1",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":-81.0,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.2",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":26.0,
+                              "width":-101.723079660188,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.3",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":52.0,
+                              "width":-130.5284446207432,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.4",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":78.0,
+                              "width":-127.5656618560784,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.5",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":104.0,
+                              "width":-111.3384716071192,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.6",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":130.0,
+                              "width":-88.0450444644344,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.7",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":156.0,
+                              "width":-84.2346734539568,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.8",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":182.0,
+                              "width":-55.85760488423456,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.9",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":208.0,
+                              "width":-17.29088735525344,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.1.10",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":234.0,
+                              "width":-2.603182268326088,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Collection",
+                        "id":"2.2",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":156.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"Spacing",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":3.0,
+                        "curve":"None",
+                        "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["y","width"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.1",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":75.0,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.2",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":26.0,
+                              "width":93.0238933518584,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.3",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":52.0,
+                              "width":119.0182296787376,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.4",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":78.0,
+                              "width":120.5432303605032,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.5",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":104.0,
+                              "width":109.5745642803936,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.6",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":130.0,
+                              "width":89.6731977362528,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.7",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":156.0,
+                              "width":95.510110933932,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.8",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":182.0,
+                              "width":65.95495183868432,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.9",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":208.0,
+                              "width":26.83355317264728,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"2.2.10",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":234.0,
+                              "width":4.556773801851816,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":2,
+                  "prefix":"B.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":758.5,
+                  "y":142.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+                  "variable":["y","width","fill"],
+                  "components":[
+                      {
+                        "type":"Collection",
+                        "id":"3.1",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":156.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"Spacing",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":3.0,
+                        "curve":"None",
+                        "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["y","width"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.1",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":-71.0,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.2",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":26.0,
+                              "width":-85.8144901722616,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.3",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":52.0,
+                              "width":-85.574294356376,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.4",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":78.0,
+                              "width":-107.4604179266456,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.5",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":104.0,
+                              "width":-124.1204059715872,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.6",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":130.0,
+                              "width":-115.0304955641568,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.7",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":156.0,
+                              "width":-92.073498981396,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.8",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":182.0,
+                              "width":-68.14180153898904,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.9",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":208.0,
+                              "width":-42.23333631753696,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.1.10",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":234.0,
+                              "width":-8.26689570755536,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0x234ae3ac",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"Collection",
+                        "id":"3.2",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xd9cccc80",
+                        "x":156.0,
+                        "y":0.0,
+                        "sticky-y":"Yes",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"Spacing",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":3.0,
+                        "curve":"None",
+                        "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                        "variable":["y","width"],
+                        "components":[
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.1",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":64.0,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.2",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":26.0,
+                              "width":78.39720532179687,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.3",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":52.0,
+                              "width":76.87430166018808,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.4",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":78.0,
+                              "width":97.8784036116768,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.5",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":104.0,
+                              "width":117.6788644924,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.6",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":130.0,
+                              "width":116.0830037514864,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.7",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":156.0,
+                              "width":100.748902911688,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.8",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":182.0,
+                              "width":78.43353312368224,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.9",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":208.0,
+                              "width":58.04534568880568,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            },
+                            {
+                              "type":"Rectangle",
+                              "id":"3.2.10",
+                              "level":0,
+                              "reference-x":"Left",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":234.0,
+                              "width":11.3507046048504,
+                              "height":23.0,
+                              "thickness":0.5,
+                              "rotation":0.0,
+                              "fill":"0xde2323b1",
+                              "stroke":"0x50508000",
+                              "shape":"Rectangle",
+                              "lock":"false"
+                            }
+                          ]
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Text",
+            "level":0,
+            "reference-x":"Left",
+            "reference-y":"Bottom",
+            "x":94.0,
+            "y":1295.0,
+            "width":272.0,
+            "height":23.0,
+            "rotation":0.0,
+            "fill":"0x4d4d4dff",
+            "text":"Greek population evolution",
+            "fontsize":20.0,
+            "lock":"false"
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Column",
+            "row":2,
+            "column":0,
+            "nrows":60,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["y"],
+            "variables":[
+                {
+                  "name":"y",
+                  "type":"Functional",
+                  "axis":true,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Age"],
+                  "function":"0.39*y"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":2,
+            "column":1,
+            "nrows":60,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["width"],
+            "variables":[
+                {
+                  "name":"width",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Percentage"],
+                  "function":"width/8"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":8,
+            "column":2,
+            "nrows":3,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":true,
+            "network":false,
+            "properties":["B.x"],
+            "variables":[
+                {
+                  "name":"B.x",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Year"],
+                  "mappings":[
+                      {
+                        "from":"75.5",
+                        "to":"1980"
+                      },
+                      {
+                        "from":"417.0",
+                        "to":"2000"
+                      },
+                      {
+                        "from":"758.5",
+                        "to":"2020"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":9,
+            "column":3,
+            "nrows":3,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":true,
+            "network":false,
+            "properties":["B.y"],
+            "variables":[
+                {
+                  "name":"B.y",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Population (x1000)"],
+                  "function":"9000+10*B.y"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/people-infographics.json b/gallery/people-infographics.json
new file mode 100644
index 0000000000000000000000000000000000000000..03240723e99642230427d78ddec9fda583b77220
--- /dev/null
+++ b/gallery/people-infographics.json
@@ -0,0 +1,1733 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":5,
+        "prefix":"E.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":308.0,
+        "y":304.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"Distance",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":297.875,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["D.sticky-x","D.sticky-y","D.distribution-x","D.delta-x","D.distribution-y","D.delta-y","D.y","D.curve","D.stroke","D.thickness","D.rotation","C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.rotation","B.sticky-x1","B.sticky-y1","B.distribution-x1","B.delta-x1","B.distribution-y1","B.delta-y1","B.x1","B.y1","B.rotation1","B.sticky-y2","B.distribution-y2","A.sticky-x1.1","A.sticky-y1.1","A.distribution-x1.1","A.delta-x1.1","A.distribution-y1.1","A.delta-y1.1","A.x1.1","A.y1.1","A.rotation1.1","A.sticky-x1.2","A.distribution-x1.2","A.delta-x1.2","A.y1.2","A.delta-x1.3","A.delta-x2.1","A.y2.1","reference-x1.1.1","reference-y1.1.1","x1.1.1","y1.1.1","width1.1.1","height1.1.1","shape1.1.1","fill1.1.1","stroke1.1.1","thickness1.1.1","rotation1.1.1","x1.1.2","rotation1.1.2","x1.2.1","width1.2.1","shape1.2.1","rotation1.2.1","x1.3.1","width1.3.1","shape1.3.1","rotation1.3.1","x1.3.2","rotation1.3.2","x2.1.1","width2.1.1","height2.1.1"],
+        "variable":["D.x","C.x","B.sticky-x2","B.distribution-x2","B.delta-x2","B.delta-y2","B.x2","B.y2","B.rotation2","A.sticky-y1.2","A.distribution-y1.2","A.delta-y1.2","A.x1.2","A.rotation1.2","A.sticky-x1.3","A.sticky-y1.3","A.distribution-x1.3","A.distribution-y1.3","A.delta-y1.3","A.x1.3","A.y1.3","A.rotation1.3","A.sticky-x2.1","A.sticky-y2.1","A.distribution-x2.1","A.distribution-y2.1","A.delta-y2.1","A.x2.1","A.rotation2.1","reference-x1.1.2","reference-y1.1.2","y1.1.2","width1.1.2","height1.1.2","shape1.1.2","fill1.1.2","stroke1.1.2","thickness1.1.2","reference-x1.2.1","reference-y1.2.1","y1.2.1","height1.2.1","fill1.2.1","stroke1.2.1","thickness1.2.1","reference-x1.3.1","reference-y1.3.1","y1.3.1","height1.3.1","fill1.3.1","stroke1.3.1","thickness1.3.1","reference-x1.3.2","reference-y1.3.2","y1.3.2","width1.3.2","height1.3.2","shape1.3.2","fill1.3.2","stroke1.3.2","thickness1.3.2","reference-x2.1.1","reference-y2.1.1","y2.1.1","shape2.1.1","fill2.1.1","stroke2.1.1","thickness2.1.1","rotation2.1.1"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":4,
+              "prefix":"D.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":34.0,
+              "y":12.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":89.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.rotation","B.sticky-x1","B.sticky-y1","B.distribution-x1","B.delta-x1","B.distribution-y1","B.delta-y1","B.x1","B.y1","B.rotation1","B.sticky-y2","B.distribution-y2","A.sticky-x1.1","A.sticky-y1.1","A.distribution-x1.1","A.delta-x1.1","A.distribution-y1.1","A.delta-y1.1","A.x1.1","A.y1.1","A.rotation1.1","A.sticky-x1.2","A.distribution-x1.2","A.delta-x1.2","A.y1.2","A.delta-x2.1","A.y2.1","reference-x1.1.1","reference-y1.1.1","x1.1.1","y1.1.1","width1.1.1","height1.1.1","shape1.1.1","stroke1.1.1","thickness1.1.1","rotation1.1.1","x1.1.2","rotation1.1.2","x1.2.1","rotation1.2.1","width1.3.1","shape1.3.1","rotation1.3.1","rotation1.3.2","x2.1.1","width2.1.1","height2.1.1"],
+              "variable":["C.x","B.sticky-x2","B.distribution-x2","B.delta-x2","B.delta-y2","B.x2","B.y2","B.rotation2","A.sticky-y1.2","A.distribution-y1.2","A.delta-y1.2","A.x1.2","A.rotation1.2","A.sticky-x1.3","A.sticky-y1.3","A.distribution-x1.3","A.delta-x1.3","A.distribution-y1.3","A.delta-y1.3","A.x1.3","A.y1.3","A.rotation1.3","A.sticky-x2.1","A.sticky-y2.1","A.distribution-x2.1","A.distribution-y2.1","A.delta-y2.1","A.x2.1","A.rotation2.1","fill1.1.1","reference-x1.1.2","reference-y1.1.2","y1.1.2","width1.1.2","height1.1.2","shape1.1.2","fill1.1.2","stroke1.1.2","thickness1.1.2","reference-x1.2.1","reference-y1.2.1","y1.2.1","width1.2.1","height1.2.1","shape1.2.1","fill1.2.1","stroke1.2.1","thickness1.2.1","reference-x1.3.1","reference-y1.3.1","x1.3.1","y1.3.1","height1.3.1","fill1.3.1","stroke1.3.1","thickness1.3.1","reference-x1.3.2","reference-y1.3.2","x1.3.2","y1.3.2","width1.3.2","height1.3.2","shape1.3.2","fill1.3.2","stroke1.3.2","thickness1.3.2","reference-x2.1.1","reference-y2.1.1","y2.1.1","shape2.1.1","fill2.1.1","stroke2.1.1","thickness2.1.1","rotation2.1.1"],
+              "components":[
+                  {
+                    "type":"Group",
+                    "id":"1.1",
+                    "level":3,
+                    "prefix":"C.",
+                    "x":-58.0,
+                    "y":19.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":-69.0,
+                    "common":["B.sticky-x","B.distribution-x","B.delta-x","B.delta-y","B.x","B.rotation","A.sticky-x","A.sticky-y","A.distribution-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["B.sticky-y","B.distribution-y","B.y","A.delta-x","A.y","x"],
+                    "public":["C.x","C.y","height1.1.1","height1.1.2","height1.3.1","height1.3.2","height1.2.1"],
+                    "bindings":[
+                        ["B.sticky-x1","B.sticky-x2"],
+                        ["B.distribution-x1","B.distribution-x2"],
+                        ["B.delta-x1","B.delta-x2"],
+                        ["B.delta-y1","B.delta-y2"],
+                        ["B.x1","B.x2"],
+                        ["B.rotation1","B.rotation2"],
+                        ["A.sticky-x1.1","A.sticky-x1.3"],
+                        ["A.sticky-x1.2","A.sticky-x2.1"],
+                        ["A.sticky-y1.1","A.sticky-y1.2","A.sticky-y1.3","A.sticky-y2.1"],
+                        ["A.distribution-x1.1","A.distribution-x1.3"],
+                        ["A.distribution-x1.2","A.distribution-x2.1"],
+                        ["A.distribution-y1.1","A.distribution-y1.2","A.distribution-y1.3","A.distribution-y2.1"],
+                        ["A.delta-y1.1","A.delta-y1.2","A.delta-y1.3","A.delta-y2.1"],
+                        ["A.x1.1","A.x1.2","A.x1.3","A.x2.1"],
+                        ["A.rotation1.1","A.rotation1.2","A.rotation1.3","A.rotation2.1"],
+                        ["reference-x1.1.1","reference-x1.1.2","reference-x1.2.1","reference-x1.3.1","reference-x1.3.2","reference-x2.1.1"],
+                        ["reference-y1.1.1","reference-y1.1.2","reference-y1.2.1","reference-y1.3.1","reference-y1.3.2","reference-y2.1.1"],
+                        ["y1.1.1","y1.1.2","y1.2.1","y1.3.1","y1.3.2","y2.1.1"],
+                        ["width1.1.1","width1.1.2"],
+                        ["width1.2.1"],
+                        ["width1.3.1","width1.3.2"],
+                        ["width2.1.1"],
+                        ["height1.1.1","height1.1.2","height1.3.1","height1.3.2"],
+                        ["height1.2.1"],
+                        ["height2.1.1"],
+                        ["shape1.1.1","shape1.1.2"],
+                        ["shape1.2.1"],
+                        ["shape1.3.1","shape1.3.2","shape2.1.1"],
+                        ["fill1.1.1","fill1.1.2","fill1.2.1","fill1.3.1","fill1.3.2","fill2.1.1"],
+                        ["stroke1.1.1","stroke1.1.2","stroke1.2.1","stroke1.3.1","stroke1.3.2","stroke2.1.1"],
+                        ["thickness1.1.1","thickness1.1.2","thickness1.2.1","thickness1.3.1","thickness1.3.2","thickness2.1.1"],
+                        ["rotation1.1.1"],
+                        ["rotation1.1.2"],
+                        ["rotation1.2.1","rotation2.1.1"],
+                        ["rotation1.3.1"],
+                        ["rotation1.3.2"]
+                      ],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"1.1.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"Spacing",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.x1.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.1.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":41.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.1.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-29.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":10.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.1.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":28.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-10.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.1.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":68.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x1.2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Triangle",
+                                      "id":"1.1.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":125.0,
+                                      "height":134.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Triangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.1.1.3",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":198.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.3.1","y3.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"1.1.1.3.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-16.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-160.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"1.1.1.3.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":15.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":160.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"1.1.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":201.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.y1","A.x2.1","A.y2.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.1.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x2.1.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"1.1.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":44.0,
+                                      "height":46.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  },
+                  {
+                    "type":"Group",
+                    "id":"1.2",
+                    "level":3,
+                    "prefix":"C.",
+                    "x":31.0,
+                    "y":19.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":-69.0,
+                    "common":["B.sticky-x","B.distribution-x","B.delta-x","B.delta-y","B.x","B.rotation","A.sticky-x","A.sticky-y","A.distribution-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["B.sticky-y","B.distribution-y","B.y","A.delta-x","A.y","x"],
+                    "public":["C.x","C.y","height1.1.1","height1.1.2","height1.3.1","height1.3.2","height1.2.1"],
+                    "bindings":[
+                        ["B.sticky-x1","B.sticky-x2"],
+                        ["B.distribution-x1","B.distribution-x2"],
+                        ["B.delta-x1","B.delta-x2"],
+                        ["B.delta-y1","B.delta-y2"],
+                        ["B.x1","B.x2"],
+                        ["B.rotation1","B.rotation2"],
+                        ["A.sticky-x1.1","A.sticky-x1.3"],
+                        ["A.sticky-x1.2","A.sticky-x2.1"],
+                        ["A.sticky-y1.1","A.sticky-y1.2","A.sticky-y1.3","A.sticky-y2.1"],
+                        ["A.distribution-x1.1","A.distribution-x1.3"],
+                        ["A.distribution-x1.2","A.distribution-x2.1"],
+                        ["A.distribution-y1.1","A.distribution-y1.2","A.distribution-y1.3","A.distribution-y2.1"],
+                        ["A.delta-y1.1","A.delta-y1.2","A.delta-y1.3","A.delta-y2.1"],
+                        ["A.x1.1","A.x1.2","A.x1.3","A.x2.1"],
+                        ["A.rotation1.1","A.rotation1.2","A.rotation1.3","A.rotation2.1"],
+                        ["reference-x1.1.1","reference-x1.1.2","reference-x1.2.1","reference-x1.3.1","reference-x1.3.2","reference-x2.1.1"],
+                        ["reference-y1.1.1","reference-y1.1.2","reference-y1.2.1","reference-y1.3.1","reference-y1.3.2","reference-y2.1.1"],
+                        ["y1.1.1","y1.1.2","y1.2.1","y1.3.1","y1.3.2","y2.1.1"],
+                        ["width1.1.1","width1.1.2"],
+                        ["width1.2.1"],
+                        ["width1.3.1","width1.3.2"],
+                        ["width2.1.1"],
+                        ["height1.1.1","height1.1.2","height1.3.1","height1.3.2"],
+                        ["height1.2.1"],
+                        ["height2.1.1"],
+                        ["shape1.1.1","shape1.1.2"],
+                        ["shape1.2.1"],
+                        ["shape1.3.1","shape1.3.2","shape2.1.1"],
+                        ["fill1.1.1","fill1.1.2","fill1.2.1","fill1.3.1","fill1.3.2","fill2.1.1"],
+                        ["stroke1.1.1","stroke1.1.2","stroke1.2.1","stroke1.3.1","stroke1.3.2","stroke2.1.1"],
+                        ["thickness1.1.1","thickness1.1.2","thickness1.2.1","thickness1.3.1","thickness1.3.2","thickness2.1.1"],
+                        ["rotation1.1.1"],
+                        ["rotation1.1.2"],
+                        ["rotation1.2.1","rotation2.1.1"],
+                        ["rotation1.3.1"],
+                        ["rotation1.3.2"]
+                      ],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"1.2.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"Spacing",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.x1.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.2.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":41.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.1.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-29.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":10.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":28.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-10.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.2.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":68.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x1.2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"1.2.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":55.0,
+                                      "height":80.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"1.2.1.3",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":144.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":41.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.3.1","y3.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"1.2.1.3.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-26.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-160.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"1.2.1.3.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":26.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":160.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"1.2.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":147.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.y1","A.x2.1","A.y2.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"1.2.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x2.1.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"1.2.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":44.0,
+                                      "height":46.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":4,
+              "prefix":"D.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":331.875,
+              "y":12.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":89.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.rotation","B.sticky-x1","B.sticky-y1","B.distribution-x1","B.delta-x1","B.distribution-y1","B.delta-y1","B.x1","B.y1","B.rotation1","B.sticky-y2","B.distribution-y2","A.sticky-x1.1","A.sticky-y1.1","A.distribution-x1.1","A.delta-x1.1","A.distribution-y1.1","A.delta-y1.1","A.x1.1","A.y1.1","A.rotation1.1","A.sticky-x1.2","A.distribution-x1.2","A.delta-x1.2","A.y1.2","A.delta-x2.1","A.y2.1","reference-x1.1.1","reference-y1.1.1","x1.1.1","y1.1.1","width1.1.1","height1.1.1","shape1.1.1","stroke1.1.1","thickness1.1.1","rotation1.1.1","x1.1.2","rotation1.1.2","x1.2.1","rotation1.2.1","width1.3.1","shape1.3.1","rotation1.3.1","rotation1.3.2","x2.1.1","width2.1.1","height2.1.1"],
+              "variable":["C.x","B.sticky-x2","B.distribution-x2","B.delta-x2","B.delta-y2","B.x2","B.y2","B.rotation2","A.sticky-y1.2","A.distribution-y1.2","A.delta-y1.2","A.x1.2","A.rotation1.2","A.sticky-x1.3","A.sticky-y1.3","A.distribution-x1.3","A.delta-x1.3","A.distribution-y1.3","A.delta-y1.3","A.x1.3","A.y1.3","A.rotation1.3","A.sticky-x2.1","A.sticky-y2.1","A.distribution-x2.1","A.distribution-y2.1","A.delta-y2.1","A.x2.1","A.rotation2.1","fill1.1.1","reference-x1.1.2","reference-y1.1.2","y1.1.2","width1.1.2","height1.1.2","shape1.1.2","fill1.1.2","stroke1.1.2","thickness1.1.2","reference-x1.2.1","reference-y1.2.1","y1.2.1","width1.2.1","height1.2.1","shape1.2.1","fill1.2.1","stroke1.2.1","thickness1.2.1","reference-x1.3.1","reference-y1.3.1","x1.3.1","y1.3.1","height1.3.1","fill1.3.1","stroke1.3.1","thickness1.3.1","reference-x1.3.2","reference-y1.3.2","x1.3.2","y1.3.2","width1.3.2","height1.3.2","shape1.3.2","fill1.3.2","stroke1.3.2","thickness1.3.2","reference-x2.1.1","reference-y2.1.1","y2.1.1","shape2.1.1","fill2.1.1","stroke2.1.1","thickness2.1.1","rotation2.1.1"],
+              "components":[
+                  {
+                    "type":"Group",
+                    "id":"2.1",
+                    "level":3,
+                    "prefix":"C.",
+                    "x":-58.0,
+                    "y":19.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":-69.0,
+                    "common":["B.sticky-x","B.distribution-x","B.delta-x","B.delta-y","B.x","B.rotation","A.sticky-x","A.sticky-y","A.distribution-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["B.sticky-y","B.distribution-y","B.y","A.delta-x","A.y","x"],
+                    "public":["C.x","C.y","height1.1.1","height1.1.2","height1.3.1","height1.3.2","height1.2.1","fill1.1.1","fill1.1.2","fill1.2.1","fill1.3.1","fill1.3.2","fill2.1.1"],
+                    "bindings":[
+                        ["B.sticky-x1","B.sticky-x2"],
+                        ["B.distribution-x1","B.distribution-x2"],
+                        ["B.delta-x1","B.delta-x2"],
+                        ["B.delta-y1","B.delta-y2"],
+                        ["B.x1","B.x2"],
+                        ["B.rotation1","B.rotation2"],
+                        ["A.sticky-x1.1","A.sticky-x1.3"],
+                        ["A.sticky-x1.2","A.sticky-x2.1"],
+                        ["A.sticky-y1.1","A.sticky-y1.2","A.sticky-y1.3","A.sticky-y2.1"],
+                        ["A.distribution-x1.1","A.distribution-x1.3"],
+                        ["A.distribution-x1.2","A.distribution-x2.1"],
+                        ["A.distribution-y1.1","A.distribution-y1.2","A.distribution-y1.3","A.distribution-y2.1"],
+                        ["A.delta-y1.1","A.delta-y1.2","A.delta-y1.3","A.delta-y2.1"],
+                        ["A.x1.1","A.x1.2","A.x1.3","A.x2.1"],
+                        ["A.rotation1.1","A.rotation1.2","A.rotation1.3","A.rotation2.1"],
+                        ["reference-x1.1.1","reference-x1.1.2","reference-x1.2.1","reference-x1.3.1","reference-x1.3.2","reference-x2.1.1"],
+                        ["reference-y1.1.1","reference-y1.1.2","reference-y1.2.1","reference-y1.3.1","reference-y1.3.2","reference-y2.1.1"],
+                        ["y1.1.1","y1.1.2","y1.2.1","y1.3.1","y1.3.2","y2.1.1"],
+                        ["width1.1.1","width1.1.2"],
+                        ["width1.2.1"],
+                        ["width1.3.1","width1.3.2"],
+                        ["width2.1.1"],
+                        ["height1.1.1","height1.1.2","height1.3.1","height1.3.2"],
+                        ["height1.2.1"],
+                        ["height2.1.1"],
+                        ["shape1.1.1","shape1.1.2"],
+                        ["shape1.2.1"],
+                        ["shape1.3.1","shape1.3.2","shape2.1.1"],
+                        ["fill1.1.1","fill1.1.2","fill1.2.1","fill1.3.1","fill1.3.2","fill2.1.1"],
+                        ["stroke1.1.1","stroke1.1.2","stroke1.2.1","stroke1.3.1","stroke1.3.2","stroke2.1.1"],
+                        ["thickness1.1.1","thickness1.1.2","thickness1.2.1","thickness1.3.1","thickness1.3.2","thickness2.1.1"],
+                        ["rotation1.1.1"],
+                        ["rotation1.1.2"],
+                        ["rotation1.2.1","rotation2.1.1"],
+                        ["rotation1.3.1"],
+                        ["rotation1.3.2"]
+                      ],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"2.1.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"Spacing",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.x1.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.1.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":41.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.1.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-29.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":10.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.1.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":28.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-10.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.1.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":68.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x1.2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Triangle",
+                                      "id":"2.1.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":125.0,
+                                      "height":77.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Triangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.1.1.3",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":141.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.3.1","y3.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"2.1.1.3.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-16.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-160.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"2.1.1.3.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":15.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":160.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"2.1.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":144.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.y1","A.x2.1","A.y2.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.1.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x2.1.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"2.1.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":44.0,
+                                      "height":46.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  },
+                  {
+                    "type":"Group",
+                    "id":"2.2",
+                    "level":3,
+                    "prefix":"C.",
+                    "x":31.0,
+                    "y":19.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":-69.0,
+                    "common":["B.sticky-x","B.distribution-x","B.delta-x","B.delta-y","B.x","B.rotation","A.sticky-x","A.sticky-y","A.distribution-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["B.sticky-y","B.distribution-y","B.y","A.delta-x","A.y","x"],
+                    "public":["C.x","C.y","height1.1.1","height1.1.2","height1.3.1","height1.3.2","height1.2.1","fill1.1.1","fill1.1.2","fill1.2.1","fill1.3.1","fill1.3.2","fill2.1.1"],
+                    "bindings":[
+                        ["B.sticky-x1","B.sticky-x2"],
+                        ["B.distribution-x1","B.distribution-x2"],
+                        ["B.delta-x1","B.delta-x2"],
+                        ["B.delta-y1","B.delta-y2"],
+                        ["B.x1","B.x2"],
+                        ["B.rotation1","B.rotation2"],
+                        ["A.sticky-x1.1","A.sticky-x1.3"],
+                        ["A.sticky-x1.2","A.sticky-x2.1"],
+                        ["A.sticky-y1.1","A.sticky-y1.2","A.sticky-y1.3","A.sticky-y2.1"],
+                        ["A.distribution-x1.1","A.distribution-x1.3"],
+                        ["A.distribution-x1.2","A.distribution-x2.1"],
+                        ["A.distribution-y1.1","A.distribution-y1.2","A.distribution-y1.3","A.distribution-y2.1"],
+                        ["A.delta-y1.1","A.delta-y1.2","A.delta-y1.3","A.delta-y2.1"],
+                        ["A.x1.1","A.x1.2","A.x1.3","A.x2.1"],
+                        ["A.rotation1.1","A.rotation1.2","A.rotation1.3","A.rotation2.1"],
+                        ["reference-x1.1.1","reference-x1.1.2","reference-x1.2.1","reference-x1.3.1","reference-x1.3.2","reference-x2.1.1"],
+                        ["reference-y1.1.1","reference-y1.1.2","reference-y1.2.1","reference-y1.3.1","reference-y1.3.2","reference-y2.1.1"],
+                        ["y1.1.1","y1.1.2","y1.2.1","y1.3.1","y1.3.2","y2.1.1"],
+                        ["width1.1.1","width1.1.2"],
+                        ["width1.2.1"],
+                        ["width1.3.1","width1.3.2"],
+                        ["width2.1.1"],
+                        ["height1.1.1","height1.1.2","height1.3.1","height1.3.2"],
+                        ["height1.2.1"],
+                        ["height2.1.1"],
+                        ["shape1.1.1","shape1.1.2","shape1.2.1"],
+                        ["shape1.3.1","shape1.3.2","shape2.1.1"],
+                        ["fill1.1.1","fill1.1.2","fill1.2.1","fill1.3.1","fill1.3.2","fill2.1.1"],
+                        ["stroke1.1.1","stroke1.1.2","stroke1.2.1","stroke1.3.1","stroke1.3.2","stroke2.1.1"],
+                        ["thickness1.1.1","thickness1.1.2","thickness1.2.1","thickness1.3.1","thickness1.3.2","thickness2.1.1"],
+                        ["rotation1.1.1"],
+                        ["rotation1.1.2"],
+                        ["rotation1.2.1","rotation2.1.1"],
+                        ["rotation1.3.1"],
+                        ["rotation1.3.2"]
+                      ],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"2.2.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"Spacing",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.x1.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.2.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":41.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.1.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-29.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":10.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":28.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-10.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.2.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":68.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x1.2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"2.2.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":55.0,
+                                      "height":132.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"2.2.1.3",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":196.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":41.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.3.1","y3.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"2.2.1.3.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-26.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-160.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"2.2.1.3.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":26.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":160.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"2.2.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":199.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.y1","A.x2.1","A.y2.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"2.2.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x2.1.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"2.2.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":44.0,
+                                      "height":46.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"3",
+              "level":4,
+              "prefix":"D.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":629.75,
+              "y":12.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":89.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["C.sticky-x","C.sticky-y","C.distribution-x","C.delta-x","C.distribution-y","C.delta-y","C.y","C.rotation","B.sticky-x1","B.sticky-y1","B.distribution-x1","B.delta-x1","B.distribution-y1","B.delta-y1","B.x1","B.y1","B.rotation1","B.sticky-y2","B.distribution-y2","A.sticky-x1.1","A.sticky-y1.1","A.distribution-x1.1","A.delta-x1.1","A.distribution-y1.1","A.delta-y1.1","A.x1.1","A.y1.1","A.rotation1.1","A.sticky-x1.2","A.distribution-x1.2","A.delta-x1.2","A.y1.2","A.delta-x2.1","A.y2.1","reference-x1.1.1","reference-y1.1.1","x1.1.1","y1.1.1","width1.1.1","height1.1.1","shape1.1.1","stroke1.1.1","thickness1.1.1","rotation1.1.1","x1.1.2","rotation1.1.2","x1.2.1","rotation1.2.1","width1.3.1","shape1.3.1","rotation1.3.1","rotation1.3.2","x2.1.1","width2.1.1","height2.1.1"],
+              "variable":["C.x","B.sticky-x2","B.distribution-x2","B.delta-x2","B.delta-y2","B.x2","B.y2","B.rotation2","A.sticky-y1.2","A.distribution-y1.2","A.delta-y1.2","A.x1.2","A.rotation1.2","A.sticky-x1.3","A.sticky-y1.3","A.distribution-x1.3","A.delta-x1.3","A.distribution-y1.3","A.delta-y1.3","A.x1.3","A.y1.3","A.rotation1.3","A.sticky-x2.1","A.sticky-y2.1","A.distribution-x2.1","A.distribution-y2.1","A.delta-y2.1","A.x2.1","A.rotation2.1","fill1.1.1","reference-x1.1.2","reference-y1.1.2","y1.1.2","width1.1.2","height1.1.2","shape1.1.2","fill1.1.2","stroke1.1.2","thickness1.1.2","reference-x1.2.1","reference-y1.2.1","y1.2.1","width1.2.1","height1.2.1","shape1.2.1","fill1.2.1","stroke1.2.1","thickness1.2.1","reference-x1.3.1","reference-y1.3.1","x1.3.1","y1.3.1","height1.3.1","fill1.3.1","stroke1.3.1","thickness1.3.1","reference-x1.3.2","reference-y1.3.2","x1.3.2","y1.3.2","width1.3.2","height1.3.2","shape1.3.2","fill1.3.2","stroke1.3.2","thickness1.3.2","reference-x2.1.1","reference-y2.1.1","y2.1.1","shape2.1.1","fill2.1.1","stroke2.1.1","thickness2.1.1","rotation2.1.1"],
+              "components":[
+                  {
+                    "type":"Group",
+                    "id":"3.1",
+                    "level":3,
+                    "prefix":"C.",
+                    "x":-59.0,
+                    "y":19.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":-69.0,
+                    "common":["B.sticky-x","B.distribution-x","B.delta-x","B.delta-y","B.x","B.rotation","A.sticky-x","A.sticky-y","A.distribution-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["B.sticky-y","B.distribution-y","B.y","A.delta-x","A.y","x"],
+                    "public":["C.x","C.y","height1.1.1","height1.1.2","height1.3.1","height1.3.2","height1.2.1"],
+                    "bindings":[
+                        ["B.sticky-x1","B.sticky-x2"],
+                        ["B.distribution-x1","B.distribution-x2"],
+                        ["B.delta-x1","B.delta-x2"],
+                        ["B.delta-y1","B.delta-y2"],
+                        ["B.x1","B.x2"],
+                        ["B.rotation1","B.rotation2"],
+                        ["A.sticky-x1.1","A.sticky-x1.3"],
+                        ["A.sticky-x1.2","A.sticky-x2.1"],
+                        ["A.sticky-y1.1","A.sticky-y1.2","A.sticky-y1.3","A.sticky-y2.1"],
+                        ["A.distribution-x1.1","A.distribution-x1.3"],
+                        ["A.distribution-x1.2","A.distribution-x2.1"],
+                        ["A.distribution-y1.1","A.distribution-y1.2","A.distribution-y1.3","A.distribution-y2.1"],
+                        ["A.delta-y1.1","A.delta-y1.2","A.delta-y1.3","A.delta-y2.1"],
+                        ["A.x1.1","A.x1.2","A.x1.3","A.x2.1"],
+                        ["A.rotation1.1","A.rotation1.2","A.rotation1.3","A.rotation2.1"],
+                        ["reference-x1.1.1","reference-x1.1.2","reference-x1.2.1","reference-x1.3.1","reference-x1.3.2","reference-x2.1.1"],
+                        ["reference-y1.1.1","reference-y1.1.2","reference-y1.2.1","reference-y1.3.1","reference-y1.3.2","reference-y2.1.1"],
+                        ["y1.1.1","y1.1.2","y1.2.1","y1.3.1","y1.3.2","y2.1.1"],
+                        ["width1.1.1","width1.1.2"],
+                        ["width1.2.1"],
+                        ["width1.3.1","width1.3.2"],
+                        ["width2.1.1"],
+                        ["height1.1.1","height1.1.2","height1.3.1","height1.3.2"],
+                        ["height1.2.1"],
+                        ["height2.1.1"],
+                        ["shape1.1.1","shape1.1.2"],
+                        ["shape1.2.1"],
+                        ["shape1.3.1","shape1.3.2","shape2.1.1"],
+                        ["fill1.1.1","fill1.1.2","fill1.2.1","fill1.3.1","fill1.3.2","fill2.1.1"],
+                        ["stroke1.1.1","stroke1.1.2","stroke1.2.1","stroke1.3.1","stroke1.3.2","stroke2.1.1"],
+                        ["thickness1.1.1","thickness1.1.2","thickness1.2.1","thickness1.3.1","thickness1.3.2","thickness2.1.1"],
+                        ["rotation1.1.1"],
+                        ["rotation1.1.2"],
+                        ["rotation1.2.1","rotation2.1.1"],
+                        ["rotation1.3.1"],
+                        ["rotation1.3.2"]
+                      ],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"3.1.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"Spacing",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.x1.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.1.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":41.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.1.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-29.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":10.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.1.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":28.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-10.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.1.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":68.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x1.2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Triangle",
+                                      "id":"3.1.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":125.0,
+                                      "height":103.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Triangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.1.1.3",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":167.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":20.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.3.1","y3.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"3.1.1.3.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-16.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-160.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"3.1.1.3.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":15.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":160.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"3.1.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":170.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.y1","A.x2.1","A.y2.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.1.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x2.1.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"3.1.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":44.0,
+                                      "height":46.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0xe64d4dff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  },
+                  {
+                    "type":"Group",
+                    "id":"3.2",
+                    "level":3,
+                    "prefix":"C.",
+                    "x":30.0,
+                    "y":19.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"Spacing",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":-69.0,
+                    "common":["B.sticky-x","B.distribution-x","B.delta-x","B.delta-y","B.x","B.rotation","A.sticky-x","A.sticky-y","A.distribution-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                    "variable":["B.sticky-y","B.distribution-y","B.y","A.delta-x","A.y","x"],
+                    "public":["C.x","C.y","height1.1.1","height1.1.2","height1.3.1","height1.3.2","height1.2.1"],
+                    "bindings":[
+                        ["B.sticky-x1","B.sticky-x2"],
+                        ["B.distribution-x1","B.distribution-x2"],
+                        ["B.delta-x1","B.delta-x2"],
+                        ["B.delta-y1","B.delta-y2"],
+                        ["B.x1","B.x2"],
+                        ["B.rotation1","B.rotation2"],
+                        ["A.sticky-x1.1","A.sticky-x1.3"],
+                        ["A.sticky-x1.2","A.sticky-x2.1"],
+                        ["A.sticky-y1.1","A.sticky-y1.2","A.sticky-y1.3","A.sticky-y2.1"],
+                        ["A.distribution-x1.1","A.distribution-x1.3"],
+                        ["A.distribution-x1.2","A.distribution-x2.1"],
+                        ["A.distribution-y1.1","A.distribution-y1.2","A.distribution-y1.3","A.distribution-y2.1"],
+                        ["A.delta-y1.1","A.delta-y1.2","A.delta-y1.3","A.delta-y2.1"],
+                        ["A.x1.1","A.x1.2","A.x1.3","A.x2.1"],
+                        ["A.rotation1.1","A.rotation1.2","A.rotation1.3","A.rotation2.1"],
+                        ["reference-x1.1.1","reference-x1.1.2","reference-x1.2.1","reference-x1.3.1","reference-x1.3.2","reference-x2.1.1"],
+                        ["reference-y1.1.1","reference-y1.1.2","reference-y1.2.1","reference-y1.3.1","reference-y1.3.2","reference-y2.1.1"],
+                        ["y1.1.1","y1.1.2","y1.2.1","y1.3.1","y1.3.2","y2.1.1"],
+                        ["width1.1.1","width1.1.2"],
+                        ["width1.2.1"],
+                        ["width1.3.1","width1.3.2"],
+                        ["width2.1.1"],
+                        ["height1.1.1","height1.1.2","height1.3.1","height1.3.2"],
+                        ["height1.2.1"],
+                        ["height2.1.1"],
+                        ["shape1.1.1","shape1.1.2","shape1.2.1"],
+                        ["shape1.3.1","shape1.3.2","shape2.1.1"],
+                        ["fill1.1.1","fill1.1.2","fill1.2.1","fill1.3.1","fill1.3.2","fill2.1.1"],
+                        ["stroke1.1.1","stroke1.1.2","stroke1.2.1","stroke1.3.1","stroke1.3.2","stroke2.1.1"],
+                        ["thickness1.1.1","thickness1.1.2","thickness1.2.1","thickness1.3.1","thickness1.3.2","thickness2.1.1"],
+                        ["rotation1.1.1"],
+                        ["rotation1.1.2"],
+                        ["rotation1.2.1","rotation2.1.1"],
+                        ["rotation1.3.1"],
+                        ["rotation1.3.2"]
+                      ],
+                    "components":[
+                        {
+                          "type":"Group",
+                          "id":"3.2.1",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":0.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"Spacing",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.x1.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.2.1.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":41.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.1.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.1.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-29.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":10.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.1.1.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":28.0,
+                                      "y":0.0,
+                                      "width":16.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-10.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.2.1.2",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":68.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x1.2.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Rectangle",
+                                      "id":"3.2.1.2.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":55.0,
+                                      "height":55.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Rectangle",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              },
+                              {
+                                "type":"Group",
+                                "id":"3.2.1.3",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":119.0,
+                                "sticky-y":"No",
+                                "sticky-x":"Yes",
+                                "distribution-x":"Spacing",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":41.0,
+                                "delta-y":0.0,
+                                "common":["y1","y1.3.1","y3.1"],
+                                "variable":["reference-x","reference-y","x","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"3.2.1.3.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":-26.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":-160.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    },
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"3.2.1.3.2",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":26.0,
+                                      "y":0.0,
+                                      "width":11.0,
+                                      "height":72.0,
+                                      "thickness":1.5,
+                                      "rotation":160.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        },
+                        {
+                          "type":"Group",
+                          "id":"3.2.2",
+                          "level":2,
+                          "prefix":"B.",
+                          "x":58.0,
+                          "y":122.0,
+                          "sticky-y":"Yes",
+                          "sticky-x":"Yes",
+                          "distribution-x":"None",
+                          "distribution-y":"None",
+                          "rotation":0.0,
+                          "delta-x":0.0,
+                          "delta-y":-4.0,
+                          "common":["A.x1","A.y1","A.x2.1","A.y2.1"],
+                          "variable":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.rotation","reference-x","reference-y","x","y","width","height","shape","fill","stroke","thickness","rotation"],
+                          "components":[
+                              {
+                                "type":"Group",
+                                "id":"3.2.2.1",
+                                "level":1,
+                                "prefix":"A.",
+                                "x":0.0,
+                                "y":0.0,
+                                "sticky-y":"No",
+                                "sticky-x":"No",
+                                "distribution-x":"None",
+                                "distribution-y":"None",
+                                "rotation":0.0,
+                                "delta-x":0.0,
+                                "delta-y":0.0,
+                                "common":["x2.1.1"],
+                                "variable":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                                "components":[
+                                    {
+                                      "type":"Ellipse",
+                                      "id":"3.2.2.1.1",
+                                      "level":0,
+                                      "reference-x":"Center",
+                                      "reference-y":"Bottom",
+                                      "x":0.0,
+                                      "y":0.0,
+                                      "width":44.0,
+                                      "height":46.0,
+                                      "thickness":1.5,
+                                      "rotation":0.0,
+                                      "fill":"0x99b3ffff",
+                                      "stroke":"0x505080ff",
+                                      "shape":"Ellipse",
+                                      "lock":"false"
+                                    }
+                                  ]
+                              }
+                            ]
+                        }
+                      ]
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/people-infographics.wrk b/gallery/people-infographics.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/gallery/reanimations-deaths-France.json b/gallery/reanimations-deaths-France.json
new file mode 100644
index 0000000000000000000000000000000000000000..4bd3ec115b52d4329708851a66887121b66b4dcf
--- /dev/null
+++ b/gallery/reanimations-deaths-France.json
@@ -0,0 +1,998 @@
+{
+  "visualizations":[
+      {
+        "type":"LineChart",
+        "level":1,
+        "prefix":"A.",
+        "thickness":2.325396825396825,
+        "stroke":"0x999999ff",
+        "x":109.0,
+        "y":624.0,
+        "sticky-y":"No",
+        "sticky-x":"Yes",
+        "distribution-x":"Distance",
+        "distribution-y":"Spacing",
+        "rotation":0.0,
+        "delta-x":26.0,
+        "delta-y":0.0,
+        "curve":"TopBottom",
+        "common":["reference-x","reference-y","width","shape","stroke","thickness","rotation"],
+        "variable":["x","y","height","fill"],
+        "components":[
+            {
+              "type":"Rectangle",
+              "id":"1",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":48.0,
+              "y":0.0,
+              "width":19.0,
+              "height":51.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"2",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":74.0,
+              "y":51.0,
+              "width":19.0,
+              "height":15.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"3",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":100.0,
+              "y":66.0,
+              "width":19.0,
+              "height":20.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"4",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":126.0,
+              "y":86.0,
+              "width":19.0,
+              "height":10.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"5",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":152.0,
+              "y":96.0,
+              "width":19.0,
+              "height":15.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"6",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":178.0,
+              "y":111.0,
+              "width":19.0,
+              "height":27.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"7",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":204.0,
+              "y":138.0,
+              "width":19.0,
+              "height":29.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"8",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":230.0,
+              "y":167.0,
+              "width":19.0,
+              "height":28.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"9",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":256.0,
+              "y":195.0,
+              "width":19.0,
+              "height":28.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"10",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":282.0,
+              "y":223.0,
+              "width":19.0,
+              "height":27.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"11",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":308.0,
+              "y":250.0,
+              "width":19.0,
+              "height":32.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"12",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":334.0,
+              "y":282.0,
+              "width":19.0,
+              "height":23.733333333333334,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"13",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":360.0,
+              "y":305.73333333333335,
+              "width":19.0,
+              "height":31.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"14",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":386.0,
+              "y":336.73333333333335,
+              "width":19.0,
+              "height":29.333333333333332,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"15",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":412.0,
+              "y":366.06666666666666,
+              "width":19.0,
+              "height":29.599999999999998,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"16",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":438.0,
+              "y":395.6666666666667,
+              "width":19.0,
+              "height":24.333333333333332,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"17",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":464.0,
+              "y":420.0,
+              "width":19.0,
+              "height":17.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"18",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":490.0,
+              "y":437.0,
+              "width":19.0,
+              "height":11.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"19",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":516.0,
+              "y":448.0,
+              "width":19.0,
+              "height":9.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"20",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":542.0,
+              "y":457.0,
+              "width":19.0,
+              "height":5.933333333333334,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"21",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":568.0,
+              "y":462.93333333333334,
+              "width":19.0,
+              "height":3.7333333333333334,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"22",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":594.0,
+              "y":466.6666666666667,
+              "width":19.0,
+              "height":1.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0xff8080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"23",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":620.0,
+              "y":467.6666666666667,
+              "width":19.0,
+              "height":-5.466666666666667,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0x99b3ffff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"24",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":646.0,
+              "y":462.20000000000005,
+              "width":19.0,
+              "height":-4.0,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0x99b3ffff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"25",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":672.0,
+              "y":458.20000000000005,
+              "width":19.0,
+              "height":-8.2,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0x99b3ffff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"26",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":698.0,
+              "y":450.00000000000006,
+              "width":19.0,
+              "height":-2.533333333333333,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0x99b3ffff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"27",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":724.0,
+              "y":447.4666666666667,
+              "width":19.0,
+              "height":-1.6,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0x99b3ffff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"28",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":750.0,
+              "y":445.8666666666667,
+              "width":19.0,
+              "height":-6.066666666666666,
+              "thickness":0.0,
+              "rotation":0.0,
+              "fill":"0x99b3ffff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            }
+          ]
+      },
+      {
+        "type":"LineChart",
+        "level":1,
+        "prefix":"A.",
+        "thickness":4.4,
+        "stroke":"0x999999ff",
+        "x":910.0,
+        "y":624.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"Distance",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":26.0,
+        "delta-y":0.0,
+        "curve":"Bezier",
+        "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+        "variable":["x","y"],
+        "components":[
+            {
+              "type":"Ellipse",
+              "id":"1",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-754.0,
+              "y":4.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"2",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-728.0,
+              "y":7.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"3",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-702.0,
+              "y":9.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"4",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-676.0,
+              "y":10.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"5",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-650.0,
+              "y":13.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"6",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-624.0,
+              "y":17.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"7",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-598.0,
+              "y":22.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"8",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-572.0,
+              "y":28.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"9",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-546.0,
+              "y":33.92,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"10",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-520.0,
+              "y":40.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"11",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-494.0,
+              "y":46.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"12",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-468.0,
+              "y":52.120000000000005,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"13",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-442.0,
+              "y":60.480000000000004,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"14",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-416.0,
+              "y":70.46000000000001,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"15",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-390.0,
+              "y":80.64,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"16",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-364.0,
+              "y":90.06,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"17",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-338.0,
+              "y":101.82000000000001,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"18",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-312.0,
+              "y":110.64,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"19",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-286.0,
+              "y":117.78,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"20",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-260.0,
+              "y":129.88,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"21",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-234.0,
+              "y":142.0,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"22",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-208.0,
+              "y":152.64000000000001,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"23",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-182.0,
+              "y":160.88,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"24",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-156.0,
+              "y":171.96,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"25",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-130.0,
+              "y":178.86,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"26",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-104.0,
+              "y":185.06,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"27",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-78.0,
+              "y":191.76,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"28",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":-52.0,
+              "y":202.58,
+              "width":14.0,
+              "height":14.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffffffff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/reanimations-deaths-France.wrk b/gallery/reanimations-deaths-France.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..22dde6819229ec5a17e11ccda42564aa624af9dc
--- /dev/null
+++ b/gallery/reanimations-deaths-France.wrk
@@ -0,0 +1,4226 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":96.875,
+            "y":785.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":90.0,
+            "y":871.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+            "variable":["x","y","width","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":125.0,
+                        "y":141.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":88.0,
+                        "y":76.0,
+                        "width":18.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":116.0,
+                        "y":36.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":206.0,
+                        "y":69.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":186.0,
+                        "y":114.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":266.0,
+                        "y":107.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":216.0,
+                        "y":141.0,
+                        "width":14.0,
+                        "height":14.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":300.0,
+                        "y":188.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":30.0,
+                        "y":56.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":67.0,
+                        "y":104.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":126.0,
+                        "y":68.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":164.0,
+                        "y":71.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":147.0,
+                        "y":116.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":257.0,
+                        "y":157.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":311.0,
+                        "y":149.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":237.0,
+                        "y":97.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":143.75,
+            "y":808.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Distance",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":44.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.y","x","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":44.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":88.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":132.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":176.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":91.0,
+            "y":91.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":23.0,
+            "delta-x":0.0,
+            "delta-y":4.0,
+            "common":["reference-x","reference-y","x","shape","fill","stroke","thickness","rotation"],
+            "variable":["y","width","height"],
+            "public":["A.x","A.y","A.rotation","height2"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["shape1","shape2"],
+                ["fill1","fill2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":70.0,
+                  "height":15.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffcce6ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":19.0,
+                  "width":16.0,
+                  "height":80.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffcce6ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"LineChart",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0x99b3ffff",
+            "x":164.0,
+            "y":919.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"Bezier",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.rotation","reference-x1","reference-y1","x1","width1","height1","shape1","fill1","stroke1","thickness1","rotation1","reference-y2","y2","width2","fill2","width3"],
+            "variable":["A.x","A.y","y1","reference-x2","x2","height2","shape2","stroke2","thickness2","rotation2","reference-x3","reference-y3","x3","y3","height3","shape3","fill3","stroke3","thickness3","rotation3"],
+            "components":[
+                {
+                  "type":"Group",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":21.0,
+                  "y":165.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "public":["A.x","A.y"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1"],
+                      ["reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["height1","height3"],
+                      ["height2"],
+                      ["shape1","shape2","shape3"],
+                      ["fill1","fill3"],
+                      ["fill2"],
+                      ["stroke1","stroke2","stroke3"],
+                      ["thickness1","thickness2","thickness3"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Top",
+                        "x":0.0,
+                        "y":-41.0,
+                        "width":92.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":2.0,
+                        "width":13.0,
+                        "height":86.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":50.0,
+                        "width":55.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":124.0,
+                  "y":285.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "public":["A.x","A.y"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1"],
+                      ["reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["height1","height3"],
+                      ["height2"],
+                      ["shape1","shape2","shape3"],
+                      ["fill1","fill3"],
+                      ["fill2"],
+                      ["stroke1","stroke2","stroke3"],
+                      ["thickness1","thickness2","thickness3"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Top",
+                        "x":0.0,
+                        "y":-21.0,
+                        "width":92.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":2.0,
+                        "width":13.0,
+                        "height":46.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":30.0,
+                        "width":55.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":314.0,
+                  "y":253.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "public":["A.x","A.y"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1"],
+                      ["reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["height1","height3"],
+                      ["height2"],
+                      ["shape1","shape2","shape3"],
+                      ["fill1","fill3"],
+                      ["fill2"],
+                      ["stroke1","stroke2","stroke3"],
+                      ["thickness1","thickness2","thickness3"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Top",
+                        "x":0.0,
+                        "y":-63.0,
+                        "width":92.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":2.0,
+                        "width":13.0,
+                        "height":130.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":55.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":465.0,
+                  "y":158.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "public":["A.x","A.y"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1"],
+                      ["reference-y2","reference-y3"],
+                      ["x1","x2","x3"],
+                      ["height1","height3"],
+                      ["height2"],
+                      ["shape1","shape2","shape3"],
+                      ["fill1","fill3"],
+                      ["fill2"],
+                      ["stroke1","stroke2","stroke3"],
+                      ["thickness1","thickness2","thickness3"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Top",
+                        "x":0.0,
+                        "y":-41.0,
+                        "width":92.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":2.0,
+                        "width":13.0,
+                        "height":86.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":50.0,
+                        "width":55.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":98.0,
+            "y":1042.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":8.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Left",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":281.0,
+                  "height":146.0,
+                  "thickness":0.8174603174603174,
+                  "rotation":0.0,
+                  "fill":"0xe6e6cc5e",
+                  "stroke":"0x6680e6ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Left",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":154.0,
+                  "width":213.0,
+                  "height":25.0,
+                  "rotation":0.0,
+                  "fill":"0x4d4d4dff",
+                  "text":"Title",
+                  "fontsize":18.0,
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"LineChart",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0xb3b34dff",
+            "x":118.0,
+            "y":882.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"Bezier",
+            "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["x","y"],
+            "components":[
+                {
+                  "type":"Ellipse",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":6.0,
+                  "y":37.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":47.0,
+                  "y":49.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":76.0,
+                  "y":74.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":121.0,
+                  "y":96.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":192.0,
+                  "y":143.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"6",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":258.0,
+                  "y":179.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"7",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":310.0,
+                  "y":210.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"8",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":352.0,
+                  "y":230.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"9",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":403.0,
+                  "y":260.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"10",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":464.0,
+                  "y":303.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                }
+              ]
+          },
+          {
+            "type":"LineChart",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0x808080ff",
+            "x":81.0,
+            "y":525.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":30.0,
+            "delta-y":0.0,
+            "curve":"TopBottom",
+            "common":["reference-x","reference-y","width","shape","stroke","thickness","rotation"],
+            "variable":["x","y","height","fill"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":22.0,
+                  "y":0.0,
+                  "width":20.0,
+                  "height":51.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":52.0,
+                  "y":51.0,
+                  "width":20.0,
+                  "height":15.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":82.0,
+                  "y":66.0,
+                  "width":20.0,
+                  "height":20.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":112.0,
+                  "y":86.0,
+                  "width":20.0,
+                  "height":10.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":142.0,
+                  "y":96.0,
+                  "width":20.0,
+                  "height":15.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"6",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":172.0,
+                  "y":111.0,
+                  "width":20.0,
+                  "height":27.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"7",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":202.0,
+                  "y":138.0,
+                  "width":20.0,
+                  "height":29.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"8",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":232.0,
+                  "y":167.0,
+                  "width":20.0,
+                  "height":28.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"9",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":262.0,
+                  "y":195.0,
+                  "width":20.0,
+                  "height":28.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"10",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":292.0,
+                  "y":223.0,
+                  "width":20.0,
+                  "height":27.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"11",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":322.0,
+                  "y":250.0,
+                  "width":20.0,
+                  "height":32.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"12",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":352.0,
+                  "y":282.0,
+                  "width":20.0,
+                  "height":24.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"13",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":382.0,
+                  "y":306.0,
+                  "width":20.0,
+                  "height":31.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"14",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":412.0,
+                  "y":337.0,
+                  "width":20.0,
+                  "height":29.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"15",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":442.0,
+                  "y":366.0,
+                  "width":20.0,
+                  "height":30.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"16",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":472.0,
+                  "y":396.0,
+                  "width":20.0,
+                  "height":24.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"17",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":502.0,
+                  "y":420.0,
+                  "width":20.0,
+                  "height":17.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"18",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":532.0,
+                  "y":437.0,
+                  "width":20.0,
+                  "height":11.133333333333333,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"19",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":562.0,
+                  "y":448.1333333333333,
+                  "width":20.0,
+                  "height":9.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"20",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":592.0,
+                  "y":457.1333333333333,
+                  "width":20.0,
+                  "height":5.933333333333334,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"21",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":622.0,
+                  "y":463.06666666666666,
+                  "width":20.0,
+                  "height":3.7333333333333334,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"22",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":652.0,
+                  "y":466.8,
+                  "width":20.0,
+                  "height":1.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"23",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":682.0,
+                  "y":467.8,
+                  "width":20.0,
+                  "height":-5.466666666666667,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"24",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":712.0,
+                  "y":462.33333333333337,
+                  "width":20.0,
+                  "height":-4.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"25",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":742.0,
+                  "y":458.33333333333337,
+                  "width":20.0,
+                  "height":-8.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"26",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":772.0,
+                  "y":450.33333333333337,
+                  "width":20.0,
+                  "height":-2.533333333333333,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"27",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":802.0,
+                  "y":447.8,
+                  "width":20.0,
+                  "height":-1.6,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"28",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":832.0,
+                  "y":446.2,
+                  "width":20.0,
+                  "height":-6.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":139.0,
+            "y":1099.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":8.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Left",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":534.0,
+                  "height":258.0,
+                  "thickness":0.8174603174603174,
+                  "rotation":0.0,
+                  "fill":"0xe6e6cc5e",
+                  "stroke":"0x6680e6ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Left",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":266.0,
+                  "width":213.0,
+                  "height":25.0,
+                  "rotation":0.0,
+                  "fill":"0x4d4d4dff",
+                  "text":"Paris hospitals only",
+                  "fontsize":18.0,
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"LineChart",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0x808080ff",
+            "x":81.0,
+            "y":525.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":30.0,
+            "delta-y":0.0,
+            "curve":"TopBottom",
+            "common":["reference-x","reference-y","width","shape","stroke","thickness","rotation"],
+            "variable":["x","y","height","fill"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":22.0,
+                  "y":0.0,
+                  "width":20.0,
+                  "height":51.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":52.0,
+                  "y":51.0,
+                  "width":20.0,
+                  "height":15.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":82.0,
+                  "y":66.0,
+                  "width":20.0,
+                  "height":20.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":112.0,
+                  "y":86.0,
+                  "width":20.0,
+                  "height":10.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":142.0,
+                  "y":96.0,
+                  "width":20.0,
+                  "height":15.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"6",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":172.0,
+                  "y":111.0,
+                  "width":20.0,
+                  "height":27.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"7",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":202.0,
+                  "y":138.0,
+                  "width":20.0,
+                  "height":29.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"8",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":232.0,
+                  "y":167.0,
+                  "width":20.0,
+                  "height":28.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"9",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":262.0,
+                  "y":195.0,
+                  "width":20.0,
+                  "height":28.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"10",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":292.0,
+                  "y":223.0,
+                  "width":20.0,
+                  "height":27.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"11",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":322.0,
+                  "y":250.0,
+                  "width":20.0,
+                  "height":32.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"12",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":352.0,
+                  "y":282.0,
+                  "width":20.0,
+                  "height":24.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"13",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":382.0,
+                  "y":306.0,
+                  "width":20.0,
+                  "height":31.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"14",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":412.0,
+                  "y":337.0,
+                  "width":20.0,
+                  "height":29.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"15",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":442.0,
+                  "y":366.0,
+                  "width":20.0,
+                  "height":30.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"16",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":472.0,
+                  "y":396.0,
+                  "width":20.0,
+                  "height":24.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"17",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":502.0,
+                  "y":420.0,
+                  "width":20.0,
+                  "height":17.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"18",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":532.0,
+                  "y":437.0,
+                  "width":20.0,
+                  "height":11.133333333333333,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"19",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":562.0,
+                  "y":448.1333333333333,
+                  "width":20.0,
+                  "height":9.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"20",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":592.0,
+                  "y":457.1333333333333,
+                  "width":20.0,
+                  "height":5.933333333333334,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"21",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":622.0,
+                  "y":463.06666666666666,
+                  "width":20.0,
+                  "height":3.7333333333333334,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"22",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":652.0,
+                  "y":466.8,
+                  "width":20.0,
+                  "height":1.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"23",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":682.0,
+                  "y":467.8,
+                  "width":20.0,
+                  "height":-5.466666666666667,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"24",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":712.0,
+                  "y":462.33333333333337,
+                  "width":20.0,
+                  "height":-4.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"25",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":742.0,
+                  "y":458.33333333333337,
+                  "width":20.0,
+                  "height":-8.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"26",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":772.0,
+                  "y":450.33333333333337,
+                  "width":20.0,
+                  "height":-2.533333333333333,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"27",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":802.0,
+                  "y":447.8,
+                  "width":20.0,
+                  "height":-1.6,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"28",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":832.0,
+                  "y":446.2,
+                  "width":20.0,
+                  "height":-6.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"LineChart",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.1,
+            "stroke":"0x808080ff",
+            "x":199.0,
+            "y":1118.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":16.0,
+            "delta-y":0.0,
+            "curve":"TopBottom",
+            "common":["reference-x","reference-y","width","shape","stroke","thickness","rotation"],
+            "variable":["x","y","height","fill"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":22.0,
+                  "y":0.0,
+                  "width":12.0,
+                  "height":26.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":38.0,
+                  "y":26.0,
+                  "width":12.0,
+                  "height":4.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":54.0,
+                  "y":30.0,
+                  "width":12.0,
+                  "height":5.75,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":70.0,
+                  "y":35.75,
+                  "width":12.0,
+                  "height":5.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":86.0,
+                  "y":40.75,
+                  "width":12.0,
+                  "height":7.5,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"6",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":102.0,
+                  "y":48.25,
+                  "width":12.0,
+                  "height":7.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"7",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":118.0,
+                  "y":55.25,
+                  "width":12.0,
+                  "height":15.25,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"8",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":134.0,
+                  "y":70.5,
+                  "width":12.0,
+                  "height":11.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"9",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":150.0,
+                  "y":81.5,
+                  "width":12.0,
+                  "height":11.75,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"10",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":166.0,
+                  "y":93.25,
+                  "width":12.0,
+                  "height":16.5,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"11",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":182.0,
+                  "y":109.75,
+                  "width":12.0,
+                  "height":19.25,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"12",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":198.0,
+                  "y":129.0,
+                  "width":12.0,
+                  "height":13.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"13",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":214.0,
+                  "y":142.0,
+                  "width":12.0,
+                  "height":6.75,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"14",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":230.0,
+                  "y":148.75,
+                  "width":12.0,
+                  "height":16.5,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"15",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":246.0,
+                  "y":165.25,
+                  "width":12.0,
+                  "height":14.25,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"16",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":262.0,
+                  "y":179.5,
+                  "width":12.0,
+                  "height":15.5,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"17",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":278.0,
+                  "y":195.0,
+                  "width":12.0,
+                  "height":0.25,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"18",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":294.0,
+                  "y":195.25,
+                  "width":12.0,
+                  "height":6.5,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"19",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":310.0,
+                  "y":201.75,
+                  "width":12.0,
+                  "height":7.25,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"20",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":326.0,
+                  "y":209.0,
+                  "width":12.0,
+                  "height":0.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"21",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":342.0,
+                  "y":209.0,
+                  "width":12.0,
+                  "height":2.75,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"22",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":358.0,
+                  "y":211.75,
+                  "width":12.0,
+                  "height":1.5,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"23",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":374.0,
+                  "y":213.25,
+                  "width":12.0,
+                  "height":-6.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"24",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":390.0,
+                  "y":207.25,
+                  "width":12.0,
+                  "height":2.5,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0xff6666ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"25",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":406.0,
+                  "y":209.75,
+                  "width":12.0,
+                  "height":-7.5,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"26",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":422.0,
+                  "y":202.25,
+                  "width":12.0,
+                  "height":-1.0,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"27",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":438.0,
+                  "y":201.25,
+                  "width":12.0,
+                  "height":-2.75,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"28",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":454.0,
+                  "y":198.5,
+                  "width":12.0,
+                  "height":-1.5,
+                  "thickness":0.0,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"LineChart",
+            "level":1,
+            "prefix":"A.",
+            "thickness":2.9,
+            "stroke":"0xb3b34dff",
+            "x":963.0,
+            "y":525.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":30.0,
+            "delta-y":0.0,
+            "curve":"Bezier",
+            "common":["reference-x","reference-y","width","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["x","y"],
+            "components":[
+                {
+                  "type":"Ellipse",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-860.0,
+                  "y":4.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-830.0,
+                  "y":6.54,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-800.0,
+                  "y":9.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-770.0,
+                  "y":10.5,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-740.0,
+                  "y":12.64,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"6",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-710.0,
+                  "y":17.2,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"7",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-680.0,
+                  "y":22.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"8",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-650.0,
+                  "y":27.76,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"9",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-620.0,
+                  "y":33.92,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"10",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-590.0,
+                  "y":40.0,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"11",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-560.0,
+                  "y":46.28,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"12",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-530.0,
+                  "y":52.120000000000005,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"13",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-500.0,
+                  "y":60.480000000000004,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"14",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-470.0,
+                  "y":70.46000000000001,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"15",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-440.0,
+                  "y":80.64,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"16",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-410.0,
+                  "y":90.06,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"17",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-380.0,
+                  "y":101.82000000000001,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"18",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-350.0,
+                  "y":110.64,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"19",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-320.0,
+                  "y":117.78,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"20",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-290.0,
+                  "y":129.88,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"21",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-260.0,
+                  "y":141.82,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"22",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-230.0,
+                  "y":152.64000000000001,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"23",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-200.0,
+                  "y":160.88,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"24",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-170.0,
+                  "y":171.96,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"25",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-140.0,
+                  "y":178.86,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"26",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-110.0,
+                  "y":185.06,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"27",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-80.0,
+                  "y":191.76,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"28",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":-50.0,
+                  "y":202.58,
+                  "width":16.0,
+                  "height":16.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffffffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                }
+              ]
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Column",
+            "row":1,
+            "column":0,
+            "nrows":28,
+            "ncolumns":1,
+            "source":"2",
+            "group":"2",
+            "wide":false,
+            "network":false,
+            "properties":["x"],
+            "variables":[
+                {
+                  "name":"x",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Date"],
+                  "mappings":[
+                      {
+                        "from":"22.0",
+                        "to":"18/3"
+                      },
+                      {
+                        "from":"52.0",
+                        "to":"19/3"
+                      },
+                      {
+                        "from":"82.0",
+                        "to":"20/3"
+                      },
+                      {
+                        "from":"112.0",
+                        "to":"21/3"
+                      },
+                      {
+                        "from":"142.0",
+                        "to":"22/3"
+                      },
+                      {
+                        "from":"172.0",
+                        "to":"23/3"
+                      },
+                      {
+                        "from":"202.0",
+                        "to":"24/3"
+                      },
+                      {
+                        "from":"232.0",
+                        "to":"25/3"
+                      },
+                      {
+                        "from":"262.0",
+                        "to":"26/3"
+                      },
+                      {
+                        "from":"292.0",
+                        "to":"27/3"
+                      },
+                      {
+                        "from":"322.0",
+                        "to":"28/3"
+                      },
+                      {
+                        "from":"352.0",
+                        "to":"29/3"
+                      },
+                      {
+                        "from":"382.0",
+                        "to":"30/3"
+                      },
+                      {
+                        "from":"412.0",
+                        "to":"31/3"
+                      },
+                      {
+                        "from":"442.0",
+                        "to":"1/4"
+                      },
+                      {
+                        "from":"472.0",
+                        "to":"2/4"
+                      },
+                      {
+                        "from":"502.0",
+                        "to":"3/4"
+                      },
+                      {
+                        "from":"532.0",
+                        "to":"4/4"
+                      },
+                      {
+                        "from":"562.0",
+                        "to":"5/4"
+                      },
+                      {
+                        "from":"592.0",
+                        "to":"6/4"
+                      },
+                      {
+                        "from":"622.0",
+                        "to":"7/4"
+                      },
+                      {
+                        "from":"652.0",
+                        "to":"8/4"
+                      },
+                      {
+                        "from":"682.0",
+                        "to":"9/4"
+                      },
+                      {
+                        "from":"712.0",
+                        "to":"10/4"
+                      },
+                      {
+                        "from":"742.0",
+                        "to":"11/4"
+                      },
+                      {
+                        "from":"772.0",
+                        "to":"12/4"
+                      },
+                      {
+                        "from":"802.0",
+                        "to":"13/4"
+                      },
+                      {
+                        "from":"832.0",
+                        "to":"14/4"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":1,
+            "nrows":28,
+            "ncolumns":1,
+            "source":"2",
+            "group":"2",
+            "wide":false,
+            "network":false,
+            "properties":["height"],
+            "variables":[
+                {
+                  "name":"height",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Reanimations"],
+                  "function":"15*height"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":2,
+            "nrows":28,
+            "ncolumns":1,
+            "source":"2",
+            "group":"2",
+            "wide":false,
+            "network":false,
+            "properties":["fill"],
+            "variables":[
+                {
+                  "name":"fill",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Trend"],
+                  "mappings":[
+                      {
+                        "from":"0x8099ffff",
+                        "to":"Decr"
+                      },
+                      {
+                        "from":"0xff6666ff",
+                        "to":"incr"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Table",
+            "row":33,
+            "column":0,
+            "nrows":28,
+            "ncolumns":5,
+            "source":"3",
+            "group":"3",
+            "wide":false,
+            "network":false,
+            "properties":["id","x","y","height","fill"],
+            "variables":[
+                {
+                  "name":"fill",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Trend"],
+                  "mappings":[
+                      {
+                        "from":"0x8099ffff",
+                        "to":"A"
+                      },
+                      {
+                        "from":"0xff6666ff",
+                        "to":"B"
+                      }
+                    ]
+                },
+                {
+                  "name":"height",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Reanimations"],
+                  "function":"4*height"
+                },
+                {
+                  "name":"id",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["id"],
+                  "function":"id"
+                },
+                {
+                  "name":"x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["x"],
+                  "function":"x"
+                },
+                {
+                  "name":"y",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["y"],
+                  "function":"y"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":65,
+            "column":3,
+            "nrows":28,
+            "ncolumns":1,
+            "source":"4",
+            "group":"4",
+            "wide":true,
+            "network":false,
+            "properties":["y"],
+            "variables":[
+                {
+                  "name":"y",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Deaths"],
+                  "function":"50*y"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/red-blue-america-legend.wrk b/gallery/red-blue-america-legend.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..16f14c0aaadabc7635596bf6a2a458da6d727b39
--- /dev/null
+++ b/gallery/red-blue-america-legend.wrk
@@ -0,0 +1,11257 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":96.875,
+            "y":785.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":90.0,
+            "y":871.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+            "variable":["x","y","width","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":125.0,
+                        "y":141.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":88.0,
+                        "y":76.0,
+                        "width":18.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":116.0,
+                        "y":36.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":206.0,
+                        "y":69.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":186.0,
+                        "y":114.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":266.0,
+                        "y":107.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":216.0,
+                        "y":141.0,
+                        "width":14.0,
+                        "height":14.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":300.0,
+                        "y":188.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":30.0,
+                        "y":56.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":67.0,
+                        "y":104.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":126.0,
+                        "y":68.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":164.0,
+                        "y":71.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":147.0,
+                        "y":116.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":257.0,
+                        "y":157.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":311.0,
+                        "y":149.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":237.0,
+                        "y":97.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":143.75,
+            "y":808.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Distance",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":44.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.y","x","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":44.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":88.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":132.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":176.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":494.0,
+            "y":913.0,
+            "sticky-y":"Yes",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["y","width"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2","reference-x3"],
+                ["reference-y1"],
+                ["reference-y2","reference-y3"],
+                ["x1","x2","x3"],
+                ["height1","height3"],
+                ["height2"],
+                ["shape1","shape2","shape3"],
+                ["fill1","fill3"],
+                ["fill2"],
+                ["stroke1","stroke2","stroke3"],
+                ["thickness1","thickness2","thickness3"],
+                ["rotation1","rotation2","rotation3"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Top",
+                  "x":0.0,
+                  "y":-41.0,
+                  "width":92.0,
+                  "height":10.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e699ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":2.0,
+                  "width":13.0,
+                  "height":86.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffe6ccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":50.0,
+                  "width":55.0,
+                  "height":10.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e699ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0x808080ff",
+            "x":136.0,
+            "y":972.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["x","y","height"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":20.0,
+                  "y":133.0,
+                  "width":25.0,
+                  "height":162.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":106.0,
+                  "y":80.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":193.0,
+                  "y":206.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":281.0,
+                  "y":135.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":277.0,
+                  "y":34.0,
+                  "width":25.0,
+                  "height":49.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ],
+            "fill":"0xcce6ffff",
+            "opacity":0.3015873015873016,
+            "coloring":"Source",
+            "connections":[
+                {
+                  "origin":"2",
+                  "destination":"5",
+                  "weight":49.0
+                },
+                {
+                  "origin":"1",
+                  "destination":"3",
+                  "weight":81.0
+                },
+                {
+                  "origin":"1",
+                  "destination":"2",
+                  "weight":81.0
+                },
+                {
+                  "origin":"3",
+                  "destination":"4",
+                  "weight":81.0
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":187.0,
+            "y":1123.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":23.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["x","height"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":22.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3b3b3ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":23.0,
+                  "y":0.0,
+                  "width":22.0,
+                  "height":98.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3b3b3ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":46.0,
+                  "y":0.0,
+                  "width":22.0,
+                  "height":38.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3b3b3ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":69.0,
+                  "y":0.0,
+                  "width":22.0,
+                  "height":131.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3b3b3ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":92.0,
+                  "y":0.0,
+                  "width":22.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3b3b3ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":332.0,
+            "y":1116.3333333333333,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x","y","shape","stroke","thickness","rotation"],
+            "variable":["width","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2","reference-x3"],
+                ["reference-y1","reference-y2","reference-y3"],
+                ["x1","x2","x3"],
+                ["y1","y2","y3"],
+                ["shape1","shape2","shape3"],
+                ["stroke1","stroke2","stroke3"],
+                ["thickness1","thickness2","thickness3"],
+                ["rotation1","rotation2","rotation3"]
+              ],
+            "components":[
+                {
+                  "type":"Ellipse",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":180.0,
+                  "height":180.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x99cc99ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":124.0,
+                  "height":124.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe64d4dff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":62.0,
+                  "height":62.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff4dff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":27.0,
+            "y":530.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":14.0,
+            "common":["reference-x","reference-y","x","stroke","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["stroke1"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Left",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":690.0,
+                  "height":286.0,
+                  "thickness":4.4,
+                  "rotation":0.0,
+                  "fill":"0xf3ece5ff",
+                  "stroke":"0x666666ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Left",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":300.0,
+                  "width":179.0,
+                  "height":20.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"Add your Title",
+                  "fontsize":20.0,
+                  "lock":"false"
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Rectangle",
+            "level":0,
+            "reference-x":"Left",
+            "reference-y":"Bottom",
+            "x":266.0,
+            "y":1191.0,
+            "width":353.0,
+            "height":135.0,
+            "thickness":0.5,
+            "rotation":0.0,
+            "fill":"0xeaf0f4ff",
+            "stroke":"0xffffffff",
+            "shape":"Rectangle",
+            "lock":"false"
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":72.0,
+            "y":563.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+            "variable":["A.x","A.y","x","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":41.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-14.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-18.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-29.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.300000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-13.950000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.0999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.5999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.550000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.9000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.699999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":700.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.9,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":25.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":22.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":20.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"6",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":120.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"6.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":8.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.699999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.95,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"7",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":120.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"7.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":28.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":28.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":22.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":22.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":25.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":29.099999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":33.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":30.299999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":33.599999999999994,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"8",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":120.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"8.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.449999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.6500000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.1500000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"9",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":120.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"9.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":22.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":23.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":21.450000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":27.450000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":29.400000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":26.099999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":26.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"10",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":240.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"10.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.15000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.44999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.5999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.550000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"11",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":240.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"11.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.350000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.9000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.15000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.2000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"12",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":240.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"12.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.6,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.549999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":25.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":30.299999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":29.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":32.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"13",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":240.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"13.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.8999999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"14",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"14.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.950000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.700000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"15",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"15.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.3500000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.8,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.2,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.200000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":25.200000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":28.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"16",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"16.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.3500000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.299999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"17",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"17.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":21.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":21.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.799999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":22.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":23.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":23.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":20.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.299999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"18",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"18.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.8,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.3,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.950000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.200000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.200000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"19",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"19.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.8999999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.700000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":20.700000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"20",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":480.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"20.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.3000000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.15000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.7999999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.85,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"21",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":480.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"21.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-14.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.2000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.200000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":21.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"22",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":480.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"22.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.3000000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"23",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":480.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"23.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.8,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.8999999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.6500000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"24",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":480.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"24.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.199999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.4499999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"25",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"25.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.4499999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.3500000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.200000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"26",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"26.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.9000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.3000000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.199999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.700000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"27",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"27.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.450000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"28",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"28.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.550000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.8999999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.2,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.049999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.3,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"29",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"29.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.199999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.3,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"30",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":600.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"30.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.44999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.8999999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.5999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"31",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":720.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"31.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.700000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":20.85,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"32",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":720.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"32.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":8.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":8.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.449999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"33",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":720.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"33.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.95,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.15000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"34",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":720.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"34.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.8499999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.8999999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"35",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":720.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"35.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.30000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.8499999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.699999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.699999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"36",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":840.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"36.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-21.6,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.550000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.300000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":8.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.05,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.05,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"37",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":840.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"37.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.30000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"38",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":840.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"38.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.3,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":8.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.550000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.30000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"39",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":840.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"39.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.5999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.7999999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.3000000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.7999999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"40",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":969.0,
+                  "y":7.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"40.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.6500000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.2,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.2000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.8499999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"41",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":960.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"41.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-54.150000000000006,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-64.05000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-63.300000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-54.150000000000006,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-56.699999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-61.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-61.050000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-60.300000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"42",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":960.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"42.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.05,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-15.450000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"43",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":960.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"43.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.1500000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.3000000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.45,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"44",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":960.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"44.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-13.049999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-18.15,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-17.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-15.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-16.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"45",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1080.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"45.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.44999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.199999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"46",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1080.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"46.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.44999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.95,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.8,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"47",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1080.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"47.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.450000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-16.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-21.299999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-21.450000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-17.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-14.549999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"48",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1080.0,
+                  "y":600.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"48.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.9000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.6500000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.2,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-20.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-23.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"49",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1200.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"49.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-14.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-13.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-16.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-22.200000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-20.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-16.799999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-16.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"50",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1200.0,
+                  "y":600.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"50.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.950000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.200000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"51",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1195.0,
+                  "y":708.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"51.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.8499999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.300000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":322.0,
+            "y":1269.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":20.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+            "variable":["x","height","fill"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":11.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-10.95,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":31.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-31.7,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":51.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-7.6499999999999995,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":71.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-7.949999999999999,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":91.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-6.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"6",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":111.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-0.15000000000000002,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"7",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":131.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":6.6000000000000005,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xcc3333ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"8",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":151.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":11.7,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xcc3333ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"9",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":171.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":35.5,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xcc3333ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Column",
+            "row":1,
+            "column":0,
+            "nrows":459,
+            "ncolumns":1,
+            "source":"2",
+            "wide":false,
+            "network":false,
+            "properties":["A.id"],
+            "variables":[
+                {
+                  "name":"A.id",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["State"],
+                  "mappings":[
+                      {
+                        "from":"2.1",
+                        "to":"Hawaii"
+                      },
+                      {
+                        "from":"2.10",
+                        "to":"New Mexico"
+                      },
+                      {
+                        "from":"2.11",
+                        "to":"Colorado"
+                      },
+                      {
+                        "from":"2.12",
+                        "to":"Wyoming"
+                      },
+                      {
+                        "from":"2.13",
+                        "to":"Montana"
+                      },
+                      {
+                        "from":"2.14",
+                        "to":"Texas"
+                      },
+                      {
+                        "from":"2.15",
+                        "to":"Oklahoma"
+                      },
+                      {
+                        "from":"2.16",
+                        "to":"Kansas"
+                      },
+                      {
+                        "from":"2.17",
+                        "to":"Nebraska"
+                      },
+                      {
+                        "from":"2.18",
+                        "to":"South Dakota"
+                      },
+                      {
+                        "from":"2.19",
+                        "to":"North Dakota"
+                      },
+                      {
+                        "from":"2.2",
+                        "to":"California"
+                      },
+                      {
+                        "from":"2.20",
+                        "to":"Louisiana"
+                      },
+                      {
+                        "from":"2.21",
+                        "to":"Arkansas"
+                      },
+                      {
+                        "from":"2.22",
+                        "to":"Missouri"
+                      },
+                      {
+                        "from":"2.23",
+                        "to":"Iowa"
+                      },
+                      {
+                        "from":"2.24",
+                        "to":"Minnesota"
+                      },
+                      {
+                        "from":"2.25",
+                        "to":"Mississippi"
+                      },
+                      {
+                        "from":"2.26",
+                        "to":"Tennessee"
+                      },
+                      {
+                        "from":"2.27",
+                        "to":"Kentucky"
+                      },
+                      {
+                        "from":"2.28",
+                        "to":"Indiana"
+                      },
+                      {
+                        "from":"2.29",
+                        "to":"Illinois"
+                      },
+                      {
+                        "from":"2.3",
+                        "to":"Oregon"
+                      },
+                      {
+                        "from":"2.30",
+                        "to":"Wisconsin"
+                      },
+                      {
+                        "from":"2.31",
+                        "to":"Alabama"
+                      },
+                      {
+                        "from":"2.32",
+                        "to":"North Carolina"
+                      },
+                      {
+                        "from":"2.33",
+                        "to":"West Virginia"
+                      },
+                      {
+                        "from":"2.34",
+                        "to":"Ohio"
+                      },
+                      {
+                        "from":"2.35",
+                        "to":"Michigan"
+                      },
+                      {
+                        "from":"2.36",
+                        "to":"Georgia"
+                      },
+                      {
+                        "from":"2.37",
+                        "to":"South Carolina"
+                      },
+                      {
+                        "from":"2.38",
+                        "to":"Virginia"
+                      },
+                      {
+                        "from":"2.39",
+                        "to":"Pennsylvania"
+                      },
+                      {
+                        "from":"2.4",
+                        "to":"Washington"
+                      },
+                      {
+                        "from":"2.40",
+                        "to":"Florida"
+                      },
+                      {
+                        "from":"2.41",
+                        "to":"District of Columbia"
+                      },
+                      {
+                        "from":"2.42",
+                        "to":"Maryland"
+                      },
+                      {
+                        "from":"2.43",
+                        "to":"New Jersey"
+                      },
+                      {
+                        "from":"2.44",
+                        "to":"New York"
+                      },
+                      {
+                        "from":"2.45",
+                        "to":"Delaware"
+                      },
+                      {
+                        "from":"2.46",
+                        "to":"Connecticut"
+                      },
+                      {
+                        "from":"2.47",
+                        "to":"Massachusetts"
+                      },
+                      {
+                        "from":"2.48",
+                        "to":"Vermont"
+                      },
+                      {
+                        "from":"2.49",
+                        "to":"Rhode Island"
+                      },
+                      {
+                        "from":"2.5",
+                        "to":"Alaska"
+                      },
+                      {
+                        "from":"2.50",
+                        "to":"New Hampshire"
+                      },
+                      {
+                        "from":"2.51",
+                        "to":"Maine"
+                      },
+                      {
+                        "from":"2.6",
+                        "to":"Arizona"
+                      },
+                      {
+                        "from":"2.7",
+                        "to":"Utah"
+                      },
+                      {
+                        "from":"2.8",
+                        "to":"Nevada"
+                      },
+                      {
+                        "from":"2.9",
+                        "to":"Idaho"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":1,
+            "nrows":459,
+            "ncolumns":1,
+            "source":"2",
+            "wide":false,
+            "network":false,
+            "properties":["A.x"],
+            "variables":[
+                {
+                  "name":"A.x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["A.x"],
+                  "function":"A.x/120"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":2,
+            "nrows":459,
+            "ncolumns":1,
+            "source":"2",
+            "wide":false,
+            "network":false,
+            "properties":["A.y"],
+            "variables":[
+                {
+                  "name":"A.y",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["A.y"],
+                  "function":"A.y/100"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":3,
+            "nrows":459,
+            "ncolumns":1,
+            "source":"2",
+            "wide":false,
+            "network":false,
+            "properties":["height"],
+            "variables":[
+                {
+                  "name":"height",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["PVI"],
+                  "function":"0.6666666666666666*height"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":4,
+            "nrows":459,
+            "ncolumns":1,
+            "source":"2",
+            "wide":false,
+            "network":false,
+            "properties":["fill"],
+            "variables":[
+                {
+                  "name":"fill",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Winner"],
+                  "mappings":[
+                      {
+                        "from":"0x6680e6ff",
+                        "to":"Dem."
+                      },
+                      {
+                        "from":"0xcc3333ff",
+                        "to":"Rep."
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":5,
+            "column":7,
+            "nrows":9,
+            "ncolumns":1,
+            "source":"3",
+            "wide":true,
+            "network":false,
+            "properties":["x"],
+            "variables":[
+                {
+                  "name":"x",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Year"],
+                  "mappings":[
+                      {
+                        "from":"11.0",
+                        "to":"'80"
+                      },
+                      {
+                        "from":"31.0",
+                        "to":"'84"
+                      },
+                      {
+                        "from":"51.0",
+                        "to":"'88"
+                      },
+                      {
+                        "from":"71.0",
+                        "to":"'92"
+                      },
+                      {
+                        "from":"91.0",
+                        "to":"'96"
+                      },
+                      {
+                        "from":"111.0",
+                        "to":"'00"
+                      },
+                      {
+                        "from":"131.0",
+                        "to":"'04"
+                      },
+                      {
+                        "from":"151.0",
+                        "to":"'08"
+                      },
+                      {
+                        "from":"171.0",
+                        "to":"'12"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":5,
+            "column":8,
+            "nrows":9,
+            "ncolumns":1,
+            "source":"3",
+            "wide":true,
+            "network":false,
+            "properties":["fill"],
+            "variables":[
+                {
+                  "name":"fill",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":true,
+                  "node":false,
+                  "labels":["More votes"],
+                  "mappings":[
+                      {
+                        "from":"0x6680e6ff",
+                        "to":"Democrats"
+                      },
+                      {
+                        "from":"0xcc3333ff",
+                        "to":"Republicans"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":5,
+            "column":6,
+            "nrows":9,
+            "ncolumns":1,
+            "source":"3",
+            "group":"3",
+            "wide":false,
+            "network":false,
+            "properties":["height"],
+            "variables":[
+                {
+                  "name":"height",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["PVI"],
+                  "function":"height/2"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/red-blue-america.json b/gallery/red-blue-america.json
new file mode 100644
index 0000000000000000000000000000000000000000..f05874f89a3700cabf7e69332e8c10c97425d106
--- /dev/null
+++ b/gallery/red-blue-america.json
@@ -0,0 +1,8950 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":72.0,
+        "y":563.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+        "variable":["A.x","A.y","x","height","fill"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":-40.0,
+              "y":41.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-10.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-14.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-11.399999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-18.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-29.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":0.0,
+              "y":300.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":5.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.4,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.300000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-11.100000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-13.950000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":0.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.0499999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.0999999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.050000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.050000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.4000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.55,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":0.0,
+              "y":500.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.5999999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.6000000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.550000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.6000000000000005,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-4.949999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.9000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.699999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-8.100000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"5",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":0.0,
+              "y":700.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"5.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":18.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":16.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.649999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.649999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":18.9,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":25.049999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":22.65,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":20.1,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":18.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"6",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":120.0,
+              "y":200.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"6.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":16.950000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"6.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":15.600000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"6.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.100000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"6.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":8.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"6.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.1499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"6.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":5.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"6.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":5.699999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"6.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"6.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.95,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"7",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":120.0,
+              "y":300.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"7.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":28.950000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"7.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":28.950000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"7.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":22.049999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"7.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":22.950000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"7.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":25.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"7.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":29.099999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"7.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":33.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"7.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":30.299999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"7.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":33.599999999999994,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"8",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":120.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"8.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"8.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":17.1,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"8.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"8.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.449999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"8.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"8.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.65,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"8.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.6500000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"8.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.9500000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"8.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.1500000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"9",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":120.0,
+              "y":500.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"9.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":22.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"9.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":23.549999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"9.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":17.549999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"9.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":16.950000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"9.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":21.450000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"9.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":27.450000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"9.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":29.400000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"9.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":26.099999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"9.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":26.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"10",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":240.0,
+              "y":200.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"10.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":5.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"10.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"10.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.15000000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"10.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"10.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"10.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"10.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.44999999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"10.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.5999999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"10.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.550000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"11",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":240.0,
+              "y":300.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"11.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"11.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.350000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"11.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.9000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"11.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.6000000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"11.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.65,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"11.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.6499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"11.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"11.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.15000000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"11.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.2000000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"12",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":240.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"12.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":18.6,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"12.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":19.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"12.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":14.850000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"12.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.100000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"12.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":14.549999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"12.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":25.049999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"12.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":30.299999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"12.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":29.549999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"12.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":32.55,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"13",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":240.0,
+              "y":500.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"13.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.899999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"13.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.800000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"13.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.8999999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"13.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.6000000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"13.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.1499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"13.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":15.299999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"13.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":17.4,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"13.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.649999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"13.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"14",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":360.0,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"14.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.0499999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"14.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.800000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"14.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":5.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"14.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.1499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"14.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"14.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.950000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"14.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":16.049999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"14.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":14.850000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"14.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":14.700000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"15",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":360.0,
+              "y":100.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"15.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.3500000000000005,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"15.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"15.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.8,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"15.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.2,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"15.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.649999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"15.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":15.299999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"15.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":19.200000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"15.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":25.200000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"15.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":28.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"16",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":360.0,
+              "y":200.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"16.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"16.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":12.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"16.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.949999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"16.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.3500000000000005,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"16.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":16.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"16.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":19.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"16.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":17.1,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"16.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":17.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"16.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":18.299999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"17",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":360.0,
+              "y":300.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"17.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":21.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"17.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":21.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"17.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.799999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"17.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":16.049999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"17.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":22.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"17.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":23.1,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"17.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":23.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"17.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":20.1,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"17.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":18.299999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"18",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":360.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"18.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.149999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"18.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.8,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"18.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.55,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"18.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"18.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.3,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"18.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.950000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"18.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":16.200000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"18.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.200000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"18.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":14.399999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"19",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":360.0,
+              "y":500.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"19.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":14.850000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"19.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":16.65,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"19.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.8999999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"19.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"19.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":15.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"19.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":17.700000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"19.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":20.700000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"19.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":15.600000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"19.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":15.149999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"20",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":480.0,
+              "y":100.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"20.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.3000000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"20.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.15000000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"20.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"20.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"20.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"20.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.7999999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"20.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.6499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"20.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":14.399999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"20.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":17.85,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"21",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":480.0,
+              "y":200.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"21.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-14.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"21.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"21.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.050000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"21.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.4000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"21.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-8.399999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"21.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.2000000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"21.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":5.1,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"21.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.200000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"21.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":21.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"22",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":480.0,
+              "y":300.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"22.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.9500000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"22.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.6000000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"22.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"22.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"22.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"22.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.4000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"22.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.3000000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"22.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.65,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"22.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.800000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"23",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":480.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"23.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.55,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"23.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"23.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-10.8,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"23.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.050000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"23.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.8999999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"23.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.6000000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"23.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.6000000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"23.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"23.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.6500000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"24",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":480.0,
+              "y":500.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"24.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.899999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"24.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-12.600000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"24.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-12.600000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"24.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-8.850000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"24.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"24.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-4.199999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"24.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"24.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.4499999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"24.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"25",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":600.0,
+              "y":100.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"25.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.4499999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"25.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.0499999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"25.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.3500000000000005,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"25.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"25.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.850000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"25.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":12.299999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"25.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.200000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"25.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":14.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"25.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"26",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":600.0,
+              "y":200.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"26.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.949999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"26.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-4.65,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"26.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.55,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"26.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.9000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"26.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.3000000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"26.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.199999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"26.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.1499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"26.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":12.899999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"26.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":17.700000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"27",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":600.0,
+              "y":300.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"27.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.4,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"27.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.55,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"27.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.4000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"27.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"27.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"27.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.149999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"27.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":12.600000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"27.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":15.450000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"27.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":19.049999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"28",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":600.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"28.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.050000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"28.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":5.550000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"28.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.8999999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"28.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.2,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"28.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.399999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"28.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":12.149999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"28.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.049999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"28.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.3,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"28.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.800000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"29",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":600.0,
+              "y":500.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"29.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"29.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"29.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-4.199999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"29.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"29.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"29.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-8.100000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"29.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.3,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"29.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-11.55,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"29.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-11.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"30",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":600.0,
+              "y":600.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"30.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.9500000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"30.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.4,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"30.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.6499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"30.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"30.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.44999999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"30.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"30.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.8999999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"30.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.5999999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"30.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"31",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":720.0,
+              "y":100.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"31.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.6499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"31.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.9500000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"31.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"31.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.899999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"31.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.850000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"31.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":12.299999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"31.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":14.700000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"31.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":19.65,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"31.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":20.85,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"32",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":720.0,
+              "y":200.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"32.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.6000000000000005,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"32.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.0499999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"32.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":5.4,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"32.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.1499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"32.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":8.399999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"32.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"32.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":8.850000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"32.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.449999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"32.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.949999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"33",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":720.0,
+              "y":300.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"33.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-10.95,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"33.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-8.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"33.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.6499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"33.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.949999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"33.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"33.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.15000000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"33.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.6000000000000005,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"33.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"33.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":19.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"34",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":720.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"34.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.0499999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"34.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.6000000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"34.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"34.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.8499999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"34.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.55,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"34.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.4000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"34.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"34.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.8999999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"34.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"35",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":720.0,
+              "y":500.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"35.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"35.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.0499999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"35.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.30000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"35.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"35.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.8499999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"35.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"35.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-4.050000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"35.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.699999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"35.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.699999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"36",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":840.0,
+              "y":100.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"36.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-21.6,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"36.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"36.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":5.550000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"36.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.050000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"36.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":6.300000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"36.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":8.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"36.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.05,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"36.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.05,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"36.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.149999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"37",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":840.0,
+              "y":200.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"37.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.6499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"37.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.30000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"37.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.899999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"37.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":12.149999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"37.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":12.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"37.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":12.149999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"37.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.850000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"37.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"37.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":11.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"38",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":840.0,
+              "y":300.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"38.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.4000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"38.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"38.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"38.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.3,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"38.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":8.850000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"38.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.6499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"38.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":5.550000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"38.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.55,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"38.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.30000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"39",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":840.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"39.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"39.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"39.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.1499999999999995,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"39.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.5999999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"39.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.9500000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"39.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.7999999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"39.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.3000000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"39.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"39.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.7999999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"40",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":969.0,
+              "y":7.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"40.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.6500000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"40.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":7.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"40.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":10.2,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"40.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"40.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":4.65,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"40.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"40.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.2000000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"40.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"40.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.8499999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"41",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":960.0,
+              "y":200.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"41.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-54.150000000000006,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"41.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-64.05000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"41.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-63.300000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"41.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-57.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"41.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-54.150000000000006,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"41.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-56.699999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"41.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-61.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"41.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-61.050000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"41.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-60.300000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"42",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":960.0,
+              "y":300.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"42.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"42.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-10.05,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"42.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.6000000000000005,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"42.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-5.4,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"42.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.6000000000000005,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"42.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.149999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"42.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-12.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"42.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-12.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"42.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-15.450000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"43",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":960.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"43.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.1500000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"43.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.55,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"43.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.3000000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"43.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"43.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.4000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"43.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.899999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"43.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.45,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"43.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.6000000000000005,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"43.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-8.399999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"44",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":960.0,
+              "y":500.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"44.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-3.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"44.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"44.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-8.399999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"44.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"44.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-13.049999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"44.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-18.15,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"44.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-17.549999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"44.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-15.299999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"44.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-16.65,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"45",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":1080.0,
+              "y":300.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"45.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-4.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"45.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.4000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"45.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.4000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"45.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.44999999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"45.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-4.199999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"45.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.800000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"45.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-8.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"45.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-10.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"45.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-12.299999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"46",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":1080.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"46.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"46.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"46.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.44999999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"46.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"46.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-4.65,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"46.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-10.95,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"46.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-11.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"46.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-10.649999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"46.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-10.8,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"47",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":1080.0,
+              "y":500.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"47.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.149999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"47.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-9.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"47.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-11.7,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"47.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-12.450000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"47.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-16.950000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"47.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-21.299999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"47.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-21.450000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"47.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-17.549999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"47.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-14.549999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"48",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":1080.0,
+              "y":600.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"48.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":3.9000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"48.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.6500000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"48.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.9500000000000002,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"48.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"48.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-11.399999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"48.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-10.2,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"48.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-12.600000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"48.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-20.1,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"48.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-23.549999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"49",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":1200.0,
+              "y":400.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"49.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-12.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"49.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-14.100000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"49.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-12.899999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"49.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-13.649999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"49.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-16.950000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"49.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-22.200000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"49.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-20.4,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"49.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-16.799999999999997,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"49.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-16.950000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"50",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":1200.0,
+              "y":600.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"50.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":13.950000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"50.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":16.200000000000003,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"50.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":14.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"50.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":9.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"50.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":1.35,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"50.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":0.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"50.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.75,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"50.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-2.4000000000000004,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"50.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"51",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":1195.0,
+              "y":708.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":11.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"51.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.5,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"51.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":11.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-1.0499999999999998,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"51.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":22.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":2.8499999999999996,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcc3333ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"51.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":33.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-0.6000000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"51.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":44.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.949999999999999,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"51.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":55.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-7.800000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"51.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":66.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-6.300000000000001,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"51.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":77.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-8.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"51.9",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":88.0,
+                    "y":0.0,
+                    "width":11.0,
+                    "height":-8.25,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/red-blue-america.wrk b/gallery/red-blue-america.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..1ce8062471dbaa776efbd9b285bd89cf9d151a72
--- /dev/null
+++ b/gallery/red-blue-america.wrk
@@ -0,0 +1,11256 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":96.875,
+            "y":785.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xff9999ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":90.0,
+            "y":871.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+            "variable":["x","y","width","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":125.0,
+                        "y":141.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":88.0,
+                        "y":76.0,
+                        "width":18.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":116.0,
+                        "y":36.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":206.0,
+                        "y":69.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":186.0,
+                        "y":114.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":266.0,
+                        "y":107.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":216.0,
+                        "y":141.0,
+                        "width":14.0,
+                        "height":14.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":300.0,
+                        "y":188.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":30.0,
+                        "y":56.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":67.0,
+                        "y":104.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":126.0,
+                        "y":68.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":164.0,
+                        "y":71.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":147.0,
+                        "y":116.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":257.0,
+                        "y":157.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":311.0,
+                        "y":149.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":237.0,
+                        "y":97.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":143.75,
+            "y":808.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Distance",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":44.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.y","x","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":44.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":88.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":24.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":132.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":30.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":29.0,
+                  "y":176.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":50.25,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":21.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":71.25,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":121.5,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":171.75,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":222.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcbd7e4ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":494.0,
+            "y":913.0,
+            "sticky-y":"Yes",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["y","width"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2","reference-x3"],
+                ["reference-y1"],
+                ["reference-y2","reference-y3"],
+                ["x1","x2","x3"],
+                ["height1","height3"],
+                ["height2"],
+                ["shape1","shape2","shape3"],
+                ["fill1","fill3"],
+                ["fill2"],
+                ["stroke1","stroke2","stroke3"],
+                ["thickness1","thickness2","thickness3"],
+                ["rotation1","rotation2","rotation3"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Top",
+                  "x":0.0,
+                  "y":-41.0,
+                  "width":92.0,
+                  "height":10.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e699ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":2.0,
+                  "width":13.0,
+                  "height":86.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffe6ccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":50.0,
+                  "width":55.0,
+                  "height":10.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe6e699ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0x808080ff",
+            "x":136.0,
+            "y":972.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["x","y","height"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":20.0,
+                  "y":133.0,
+                  "width":25.0,
+                  "height":162.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":106.0,
+                  "y":80.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":193.0,
+                  "y":206.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":281.0,
+                  "y":135.0,
+                  "width":25.0,
+                  "height":81.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":277.0,
+                  "y":34.0,
+                  "width":25.0,
+                  "height":49.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x8099ffff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ],
+            "fill":"0xcce6ffff",
+            "opacity":0.3015873015873016,
+            "coloring":"Source",
+            "connections":[
+                {
+                  "origin":"2",
+                  "destination":"5",
+                  "weight":49.0
+                },
+                {
+                  "origin":"1",
+                  "destination":"3",
+                  "weight":81.0
+                },
+                {
+                  "origin":"3",
+                  "destination":"4",
+                  "weight":81.0
+                },
+                {
+                  "origin":"1",
+                  "destination":"2",
+                  "weight":81.0
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":187.0,
+            "y":1123.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":23.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["x","height"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":22.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3b3b3ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":23.0,
+                  "y":0.0,
+                  "width":22.0,
+                  "height":98.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3b3b3ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":46.0,
+                  "y":0.0,
+                  "width":22.0,
+                  "height":38.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3b3b3ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":69.0,
+                  "y":0.0,
+                  "width":22.0,
+                  "height":131.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3b3b3ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":92.0,
+                  "y":0.0,
+                  "width":22.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3b3b3ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":332.0,
+            "y":1116.3333333333333,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x","y","shape","stroke","thickness","rotation"],
+            "variable":["width","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2","reference-x3"],
+                ["reference-y1","reference-y2","reference-y3"],
+                ["x1","x2","x3"],
+                ["y1","y2","y3"],
+                ["shape1","shape2","shape3"],
+                ["stroke1","stroke2","stroke3"],
+                ["thickness1","thickness2","thickness3"],
+                ["rotation1","rotation2","rotation3"]
+              ],
+            "components":[
+                {
+                  "type":"Ellipse",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":180.0,
+                  "height":180.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x99cc99ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":124.0,
+                  "height":124.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xe64d4dff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":62.0,
+                  "height":62.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff4dff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"true"
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":27.0,
+            "y":530.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":14.0,
+            "common":["reference-x","reference-y","x","stroke","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["stroke1"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Left",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":690.0,
+                  "height":286.0,
+                  "thickness":4.4,
+                  "rotation":0.0,
+                  "fill":"0xf3ece5ff",
+                  "stroke":"0x666666ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Left",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":300.0,
+                  "width":179.0,
+                  "height":20.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"Add your Title",
+                  "fontsize":20.0,
+                  "lock":"false"
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Rectangle",
+            "level":0,
+            "reference-x":"Left",
+            "reference-y":"Bottom",
+            "x":266.0,
+            "y":1191.0,
+            "width":353.0,
+            "height":135.0,
+            "thickness":0.5,
+            "rotation":0.0,
+            "fill":"0xeaf0f4ff",
+            "stroke":"0xffffffff",
+            "shape":"Rectangle",
+            "lock":"false"
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":72.0,
+            "y":563.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+            "variable":["A.x","A.y","x","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-14.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-18.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-29.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.300000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-13.950000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.0999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.5999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.550000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.9000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.699999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":700.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.9,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":25.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":22.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":20.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"6",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":120.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"6.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":8.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.699999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"6.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.95,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"7",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":120.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"7.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":28.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":28.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":22.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":22.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":25.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":29.099999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":33.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":30.299999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"7.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":33.599999999999994,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"8",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":120.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"8.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.449999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.6500000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"8.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.1500000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"9",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":120.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"9.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":22.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":23.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":21.450000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":27.450000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":29.400000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":26.099999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"9.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":26.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"10",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":240.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"10.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.15000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.44999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.5999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"10.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.550000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"11",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":240.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"11.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.350000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.9000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.15000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"11.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.2000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"12",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":240.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"12.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.6,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.549999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":25.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":30.299999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":29.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"12.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":32.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"13",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":240.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"13.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.8999999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"13.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"14",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"14.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.950000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"14.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.700000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"15",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"15.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.3500000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.8,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.2,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.200000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":25.200000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"15.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":28.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"16",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"16.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.3500000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"16.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.299999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"17",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"17.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":21.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":21.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.799999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":22.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":23.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":23.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":20.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"17.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":18.299999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"18",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"18.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.8,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.3,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.950000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.200000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.200000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"18.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"19",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":360.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"19.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.8999999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.700000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":20.700000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"19.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"20",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":480.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"20.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.3000000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.15000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.7999999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"20.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.85,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"21",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":480.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"21.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-14.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.2000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.200000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"21.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":21.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"22",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":480.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"22.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.3000000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"22.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"23",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":480.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"23.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.8,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.8999999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"23.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.6500000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"24",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":480.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"24.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.199999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.4499999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"24.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"25",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"25.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.4499999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.3500000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.200000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"25.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"26",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"26.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.9000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.3000000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.199999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"26.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":17.700000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"27",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"27.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":15.450000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"27.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.049999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"28",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"28.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.550000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.8999999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.2,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.049999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.3,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"28.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"29",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"29.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.199999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.3,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"29.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"30",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":600.0,
+                  "y":600.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"30.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.44999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.8999999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.5999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"30.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"31",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":720.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"31.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.700000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"31.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":20.85,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"32",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":720.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"32.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":8.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":8.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.449999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"32.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"33",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":720.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"33.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.95,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.15000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"33.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":19.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"34",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":720.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"34.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.8499999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.8999999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"34.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"35",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":720.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"35.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.30000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.8499999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.699999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"35.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.699999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"36",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":840.0,
+                  "y":100.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"36.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-21.6,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.550000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.050000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":6.300000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":8.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.05,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.05,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"36.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"37",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":840.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"37.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.30000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":12.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"37.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"38",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":840.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"38.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.3,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":8.850000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.6499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":5.550000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"38.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.30000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"39",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":840.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"39.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.1499999999999995,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.5999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.7999999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.3000000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"39.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.7999999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"40",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":960.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"40.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.6500000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":7.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":10.2,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.2000000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"40.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.8499999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"41",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":960.0,
+                  "y":200.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"41.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-54.150000000000006,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-64.05000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-63.300000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-54.150000000000006,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-56.699999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-61.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-61.050000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"41.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-60.300000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"42",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":960.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"42.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.05,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-5.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"42.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-15.450000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"43",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":960.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"43.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.1500000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.55,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.3000000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.45,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.6000000000000005,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"43.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"44",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":960.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"44.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-3.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-13.049999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-18.15,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-17.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-15.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"44.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-16.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"45",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1080.0,
+                  "y":300.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"45.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.44999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.199999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"45.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.299999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"46",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1080.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"46.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.44999999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-4.65,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.95,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"46.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.8,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"47",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1080.0,
+                  "y":500.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"47.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.149999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-9.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.7,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.450000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-16.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-21.299999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-21.450000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-17.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"47.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-14.549999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"48",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1080.0,
+                  "y":600.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"48.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":3.9000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.6500000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.9500000000000002,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-11.399999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-10.2,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.600000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-20.1,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"48.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-23.549999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"49",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1200.0,
+                  "y":400.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"49.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-14.100000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-12.899999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-13.649999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-16.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-22.200000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-20.4,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-16.799999999999997,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"49.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-16.950000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"50",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1200.0,
+                  "y":600.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"50.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":13.950000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":16.200000000000003,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":14.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":9.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":1.35,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":0.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.75,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-2.4000000000000004,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"50.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"51",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":1200.0,
+                  "y":708.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Distance",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":11.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+                  "variable":["x","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"51.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.5,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":11.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-1.0499999999999998,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":22.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":2.8499999999999996,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xcc3333ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":33.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-0.6000000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":44.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.949999999999999,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":55.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-7.800000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":66.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-6.300000000000001,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":77.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"51.9",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":88.0,
+                        "y":0.0,
+                        "width":11.0,
+                        "height":-8.25,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":1,
+            "prefix":"A.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":322.0,
+            "y":1269.0,
+            "sticky-y":"No",
+            "sticky-x":"Yes",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":20.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+            "variable":["x","height","fill"],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":11.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-10.95,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":31.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-31.7,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"3",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":51.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-7.6499999999999995,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"4",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":71.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-7.949999999999999,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"5",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":91.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-6.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"6",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":111.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":-0.15000000000000002,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0x6680e6ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"7",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":131.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":6.6000000000000005,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xcc3333ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"8",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":151.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":11.7,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xcc3333ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"9",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":171.0,
+                  "y":0.0,
+                  "width":19.0,
+                  "height":35.5,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xcc3333ff",
+                  "stroke":"0x50508000",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Column",
+            "row":1,
+            "column":0,
+            "nrows":459,
+            "ncolumns":1,
+            "source":"2",
+            "wide":false,
+            "network":false,
+            "properties":["A.id"],
+            "variables":[
+                {
+                  "name":"A.id",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["State"],
+                  "mappings":[
+                      {
+                        "from":"2.1",
+                        "to":"Hawaii"
+                      },
+                      {
+                        "from":"2.10",
+                        "to":"New Mexico"
+                      },
+                      {
+                        "from":"2.11",
+                        "to":"Colorado"
+                      },
+                      {
+                        "from":"2.12",
+                        "to":"Wyoming"
+                      },
+                      {
+                        "from":"2.13",
+                        "to":"Montana"
+                      },
+                      {
+                        "from":"2.14",
+                        "to":"Texas"
+                      },
+                      {
+                        "from":"2.15",
+                        "to":"Oklahoma"
+                      },
+                      {
+                        "from":"2.16",
+                        "to":"Kansas"
+                      },
+                      {
+                        "from":"2.17",
+                        "to":"Nebraska"
+                      },
+                      {
+                        "from":"2.18",
+                        "to":"South Dakota"
+                      },
+                      {
+                        "from":"2.19",
+                        "to":"North Dakota"
+                      },
+                      {
+                        "from":"2.2",
+                        "to":"California"
+                      },
+                      {
+                        "from":"2.20",
+                        "to":"Louisiana"
+                      },
+                      {
+                        "from":"2.21",
+                        "to":"Arkansas"
+                      },
+                      {
+                        "from":"2.22",
+                        "to":"Missouri"
+                      },
+                      {
+                        "from":"2.23",
+                        "to":"Iowa"
+                      },
+                      {
+                        "from":"2.24",
+                        "to":"Minnesota"
+                      },
+                      {
+                        "from":"2.25",
+                        "to":"Mississippi"
+                      },
+                      {
+                        "from":"2.26",
+                        "to":"Tennessee"
+                      },
+                      {
+                        "from":"2.27",
+                        "to":"Kentucky"
+                      },
+                      {
+                        "from":"2.28",
+                        "to":"Indiana"
+                      },
+                      {
+                        "from":"2.29",
+                        "to":"Illinois"
+                      },
+                      {
+                        "from":"2.3",
+                        "to":"Oregon"
+                      },
+                      {
+                        "from":"2.30",
+                        "to":"Wisconsin"
+                      },
+                      {
+                        "from":"2.31",
+                        "to":"Alabama"
+                      },
+                      {
+                        "from":"2.32",
+                        "to":"North Carolina"
+                      },
+                      {
+                        "from":"2.33",
+                        "to":"West Virginia"
+                      },
+                      {
+                        "from":"2.34",
+                        "to":"Ohio"
+                      },
+                      {
+                        "from":"2.35",
+                        "to":"Michigan"
+                      },
+                      {
+                        "from":"2.36",
+                        "to":"Georgia"
+                      },
+                      {
+                        "from":"2.37",
+                        "to":"South Carolina"
+                      },
+                      {
+                        "from":"2.38",
+                        "to":"Virginia"
+                      },
+                      {
+                        "from":"2.39",
+                        "to":"Pennsylvania"
+                      },
+                      {
+                        "from":"2.4",
+                        "to":"Washington"
+                      },
+                      {
+                        "from":"2.40",
+                        "to":"Florida"
+                      },
+                      {
+                        "from":"2.41",
+                        "to":"District of Columbia"
+                      },
+                      {
+                        "from":"2.42",
+                        "to":"Maryland"
+                      },
+                      {
+                        "from":"2.43",
+                        "to":"New Jersey"
+                      },
+                      {
+                        "from":"2.44",
+                        "to":"New York"
+                      },
+                      {
+                        "from":"2.45",
+                        "to":"Delaware"
+                      },
+                      {
+                        "from":"2.46",
+                        "to":"Connecticut"
+                      },
+                      {
+                        "from":"2.47",
+                        "to":"Massachusetts"
+                      },
+                      {
+                        "from":"2.48",
+                        "to":"Vermont"
+                      },
+                      {
+                        "from":"2.49",
+                        "to":"Rhode Island"
+                      },
+                      {
+                        "from":"2.5",
+                        "to":"Alaska"
+                      },
+                      {
+                        "from":"2.50",
+                        "to":"New Hampshire"
+                      },
+                      {
+                        "from":"2.51",
+                        "to":"Maine"
+                      },
+                      {
+                        "from":"2.6",
+                        "to":"Arizona"
+                      },
+                      {
+                        "from":"2.7",
+                        "to":"Utah"
+                      },
+                      {
+                        "from":"2.8",
+                        "to":"Nevada"
+                      },
+                      {
+                        "from":"2.9",
+                        "to":"Idaho"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":1,
+            "nrows":459,
+            "ncolumns":1,
+            "source":"2",
+            "wide":false,
+            "network":false,
+            "properties":["A.x"],
+            "variables":[
+                {
+                  "name":"A.x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["GridX"],
+                  "function":"A.x/120"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":2,
+            "nrows":459,
+            "ncolumns":1,
+            "source":"2",
+            "wide":false,
+            "network":false,
+            "properties":["A.y"],
+            "variables":[
+                {
+                  "name":"A.y",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["GridY"],
+                  "function":"A.y/100"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":3,
+            "nrows":459,
+            "ncolumns":1,
+            "source":"2",
+            "wide":false,
+            "network":false,
+            "properties":["height"],
+            "variables":[
+                {
+                  "name":"height",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["PVI"],
+                  "function":"0.6666666666666666*height"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":1,
+            "column":4,
+            "nrows":459,
+            "ncolumns":1,
+            "source":"2",
+            "wide":false,
+            "network":false,
+            "properties":["fill"],
+            "variables":[
+                {
+                  "name":"fill",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Winner"],
+                  "mappings":[
+                      {
+                        "from":"0x6680e6ff",
+                        "to":"Dem."
+                      },
+                      {
+                        "from":"0xcc3333ff",
+                        "to":"Rep."
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":5,
+            "column":7,
+            "nrows":9,
+            "ncolumns":1,
+            "source":"3",
+            "wide":true,
+            "network":false,
+            "properties":["x"],
+            "variables":[
+                {
+                  "name":"x",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Year"],
+                  "mappings":[
+                      {
+                        "from":"11.0",
+                        "to":"'80"
+                      },
+                      {
+                        "from":"31.0",
+                        "to":"'84"
+                      },
+                      {
+                        "from":"51.0",
+                        "to":"'88"
+                      },
+                      {
+                        "from":"71.0",
+                        "to":"'92"
+                      },
+                      {
+                        "from":"91.0",
+                        "to":"'96"
+                      },
+                      {
+                        "from":"111.0",
+                        "to":"'00"
+                      },
+                      {
+                        "from":"131.0",
+                        "to":"'04"
+                      },
+                      {
+                        "from":"151.0",
+                        "to":"'08"
+                      },
+                      {
+                        "from":"171.0",
+                        "to":"'12"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":5,
+            "column":8,
+            "nrows":9,
+            "ncolumns":1,
+            "source":"3",
+            "wide":true,
+            "network":false,
+            "properties":["fill"],
+            "variables":[
+                {
+                  "name":"fill",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":true,
+                  "node":false,
+                  "labels":["More votes"],
+                  "mappings":[
+                      {
+                        "from":"0x6680e6ff",
+                        "to":"Democrats"
+                      },
+                      {
+                        "from":"0xcc3333ff",
+                        "to":"Republicans"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":5,
+            "column":6,
+            "nrows":9,
+            "ncolumns":1,
+            "source":"3",
+            "wide":false,
+            "network":false,
+            "properties":["height"],
+            "variables":[
+                {
+                  "name":"height",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":false,
+                  "labels":["PVI"],
+                  "function":"height/2"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/republicans-democrats-2.json b/gallery/republicans-democrats-2.json
new file mode 100644
index 0000000000000000000000000000000000000000..0c6b1ccd7c11480d7534561720a45cfc466d68bd
--- /dev/null
+++ b/gallery/republicans-democrats-2.json
@@ -0,0 +1,850 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":644.0,
+        "y":1000.0,
+        "sticky-y":"Yes",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"Distance",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":54.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+        "variable":["A.y","x"],
+        "components":[
+            {
+              "type":"LineChart",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xe699b345",
+              "x":0.0,
+              "y":28.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"StraightSolid",
+              "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+              "variable":["x","fill"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":18.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xe699b345",
+              "x":0.0,
+              "y":82.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"StraightSolid",
+              "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+              "variable":["x","fill"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":24.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xe699b345",
+              "x":0.0,
+              "y":136.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"StraightSolid",
+              "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+              "variable":["x","fill"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":92.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":136.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xe699b345",
+              "x":0.0,
+              "y":190.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"StraightSolid",
+              "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+              "variable":["x","fill"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":6.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":160.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"5",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xe699b345",
+              "x":0.0,
+              "y":244.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"StraightSolid",
+              "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+              "variable":["x","fill"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"5.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":178.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"5.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":292.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"LineChart",
+              "id":"6",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xe699b345",
+              "x":0.0,
+              "y":298.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"StraightSolid",
+              "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+              "variable":["x","fill"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"6.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":228.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"6.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":398.0,
+                    "y":0.0,
+                    "width":17.0,
+                    "height":17.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            }
+          ]
+      },
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":54.0,
+        "y":999.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"Spacing",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":37.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x1","reference-y1","x1","y1","width1","height1","fill1","rotation1","x2","width2","fill2","x3","fill3"],
+        "variable":["A.y","text1","reference-x2","reference-y2","y2","height2","text2","fontsize","rotation2","reference-x3","reference-y3","y3","width3","height3","text3","rotation3"],
+        "components":[
+            {
+              "type":"Group",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "x":0.0,
+              "y":22.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Spacing",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":10.0,
+              "delta-y":0.0,
+              "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+              "variable":["x","text","fill"],
+              "public":["text1","text2","text3"],
+              "bindings":[
+                  ["reference-x1","reference-x2","reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["y1","y2","y3"],
+                  ["width1"],
+                  ["width2","width3"],
+                  ["height1","height2","height3"],
+                  ["fontsize","fontsize","fontsize"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Text",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":368.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x696969ff",
+                    "text":"Stated support for gun rights",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":378.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "text":"9",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":438.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "text":"0",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "x":0.0,
+              "y":78.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Spacing",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":10.0,
+              "delta-y":0.0,
+              "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+              "variable":["x","text","fill"],
+              "public":["text1","text2","text3"],
+              "bindings":[
+                  ["reference-x1","reference-x2","reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["y1","y2","y3"],
+                  ["width1"],
+                  ["width2","width3"],
+                  ["height1","height2","height3"],
+                  ["fontsize","fontsize","fontsize"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Text",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":368.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x696969ff",
+                    "text":"Criticized Obama Administration",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":378.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "text":"12",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":438.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "text":"0",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "x":0.0,
+              "y":134.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Spacing",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":10.0,
+              "delta-y":0.0,
+              "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+              "variable":["x","text","fill"],
+              "public":["text1","text2","text3"],
+              "bindings":[
+                  ["reference-x1","reference-x2","reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["y1","y2","y3"],
+                  ["width1"],
+                  ["width2","width3"],
+                  ["height1","height2","height3"],
+                  ["fontsize","fontsize","fontsize"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Text",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":368.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x696969ff",
+                    "text":"Praised first responders",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":378.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "text":"68",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"3.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":438.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "text":"46",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "x":0.0,
+              "y":190.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Spacing",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":10.0,
+              "delta-y":0.0,
+              "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+              "variable":["x","text","fill"],
+              "public":["text1","text2","text3"],
+              "bindings":[
+                  ["reference-x1","reference-x2","reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["y1","y2","y3"],
+                  ["width1"],
+                  ["width2","width3"],
+                  ["height1","height2","height3"],
+                  ["fontsize","fontsize","fontsize"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Text",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":368.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x696969ff",
+                    "text":"Used phrases similar to radical Islam",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":378.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "text":"80",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"4.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":438.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "text":"3",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"5",
+              "level":1,
+              "prefix":"A.",
+              "x":0.0,
+              "y":246.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Spacing",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":10.0,
+              "delta-y":0.0,
+              "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+              "variable":["x","text","fill"],
+              "public":["text1","text2","text3"],
+              "bindings":[
+                  ["reference-x1","reference-x2","reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["y1","y2","y3"],
+                  ["width1"],
+                  ["width2","width3"],
+                  ["height1","height2","height3"],
+                  ["fontsize","fontsize","fontsize"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Text",
+                    "id":"5.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":368.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x696969ff",
+                    "text":"Condemned terrorism",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"5.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":378.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "text":"146",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"5.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":438.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "text":"89",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Group",
+              "id":"6",
+              "level":1,
+              "prefix":"A.",
+              "x":0.0,
+              "y":302.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"Spacing",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":10.0,
+              "delta-y":0.0,
+              "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+              "variable":["x","text","fill"],
+              "public":["text1","text2","text3"],
+              "bindings":[
+                  ["reference-x1","reference-x2","reference-x3"],
+                  ["reference-y1","reference-y2","reference-y3"],
+                  ["y1","y2","y3"],
+                  ["width1"],
+                  ["width2","width3"],
+                  ["height1","height2","height3"],
+                  ["fontsize","fontsize","fontsize"],
+                  ["rotation1","rotation2","rotation3"]
+                ],
+              "components":[
+                  {
+                    "type":"Text",
+                    "id":"6.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":368.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x696969ff",
+                    "text":"Thoughs & Prayers",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"6.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":378.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "text":"199",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Text",
+                    "id":"6.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":438.0,
+                    "y":0.0,
+                    "width":50.0,
+                    "height":19.0,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "text":"114",
+                    "fontsize":14.0,
+                    "lock":"false"
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/republicans-democrats-2.wrk b/gallery/republicans-democrats-2.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..97bb136c24e65ef0b585190e3b0e2d099a39188e
--- /dev/null
+++ b/gallery/republicans-democrats-2.wrk
@@ -0,0 +1,2835 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":490.0,
+            "y":937.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+            "variable":["x","y","width","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":125.0,
+                        "y":141.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":88.0,
+                        "y":76.0,
+                        "width":18.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":116.0,
+                        "y":36.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":206.0,
+                        "y":69.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":186.0,
+                        "y":114.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":266.0,
+                        "y":107.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":216.0,
+                        "y":141.0,
+                        "width":14.0,
+                        "height":14.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":300.0,
+                        "y":188.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":30.0,
+                        "y":56.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":67.0,
+                        "y":104.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":126.0,
+                        "y":68.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":164.0,
+                        "y":71.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":147.0,
+                        "y":116.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":257.0,
+                        "y":157.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":311.0,
+                        "y":149.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":237.0,
+                        "y":97.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":1004.0,
+            "y":1228.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":66.0,
+                  "height":62.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":72.0,
+                  "width":75.0,
+                  "height":19.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"my label",
+                  "fontsize":14.0,
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":1004.0,
+            "y":935.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+            "variable":["y","width","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":-72.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":-82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":-89.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":-93.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":-51.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":-26.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":86.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":103.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":125.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":66.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":36.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":9.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":978.0,
+            "y":803.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":-124.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x1","y","stroke","thickness","rotation"],
+            "variable":["width","height","shape","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["y1","y2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":106.0,
+                  "height":106.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff9999ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":78.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":125.0,
+            "y":1120.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":270.5,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":23.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":50.0,
+                        "width":37.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":222.5,
+            "y":1071.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":4.0,
+            "common":["reference-x","reference-y","x","shape","stroke","thickness","rotation"],
+            "variable":["y","width","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["shape1","shape2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":88.0,
+                  "height":12.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffccccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":16.0,
+                  "width":16.0,
+                  "height":91.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3ccffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":586.0,
+            "y":1001.0,
+            "sticky-y":"Yes",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Distance",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":54.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.y","x"],
+            "components":[
+                {
+                  "type":"LineChart",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xe699b345",
+                  "x":0.0,
+                  "y":28.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"StraightSolid",
+                  "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                  "variable":["x","fill"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":18.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xe699b345",
+                  "x":0.0,
+                  "y":82.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"StraightSolid",
+                  "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                  "variable":["x","fill"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":24.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xe699b345",
+                  "x":0.0,
+                  "y":136.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"StraightSolid",
+                  "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                  "variable":["x","fill"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":92.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":136.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xe699b345",
+                  "x":0.0,
+                  "y":190.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"StraightSolid",
+                  "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                  "variable":["x","fill"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":6.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":160.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xe699b345",
+                  "x":0.0,
+                  "y":244.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"StraightSolid",
+                  "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                  "variable":["x","fill"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":178.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":292.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"6",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xe699b345",
+                  "x":0.0,
+                  "y":298.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"StraightSolid",
+                  "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                  "variable":["x","fill"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"6.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":228.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"6.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":398.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":54.0,
+            "y":999.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":35.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x1","reference-y1","x1","y1","width1","height1","fill1","rotation1","x2","width2","fill2","x3","fill3"],
+            "variable":["A.y","text1","reference-x2","reference-y2","y2","height2","text2","fontsize","rotation2","reference-x3","reference-y3","y3","width3","height3","text3","rotation3"],
+            "components":[
+                {
+                  "type":"Group",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":27.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Stated support for gun rights",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"9",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"0",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":81.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Criticized Obama Administration",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"12",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"0",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":135.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Praised first responders",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"68",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"46",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":189.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Used phrases similar to radical Islam",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"80",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"3",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":243.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Condemned terrorism",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"146",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"89",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"6",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":297.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"6.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Thoughs & Prayers",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"6.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"199",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"6.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"114",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Text",
+            "level":0,
+            "reference-x":"Left",
+            "reference-y":"Bottom",
+            "x":29.0,
+            "y":1344.0,
+            "width":482.0,
+            "height":22.0,
+            "rotation":0.0,
+            "fill":"0xcc3333ff",
+            "text":"Topics Mentioned More by Republicans",
+            "fontsize":20.0,
+            "lock":"false"
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":581.0,
+            "y":741.0,
+            "sticky-y":"Yes",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Distance",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":54.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.y","x"],
+            "components":[
+                {
+                  "type":"LineChart",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xb3ccff6c",
+                  "x":0.0,
+                  "y":26.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"StraightSolid",
+                  "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                  "variable":["x","fill"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":158.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xb3ccff6c",
+                  "x":0.0,
+                  "y":80.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"StraightSolid",
+                  "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                  "variable":["x","fill"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":188.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":48.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"LineChart",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xb3ccff6c",
+                  "x":0.0,
+                  "y":134.0,
+                  "sticky-y":"No",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"StraightSolid",
+                  "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                  "variable":["x","fill"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":246.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0x8099ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":38.0,
+                        "y":0.0,
+                        "width":17.0,
+                        "height":17.0,
+                        "thickness":0.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x505080ff",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":51.0,
+            "y":741.0,
+            "sticky-y":"Yes",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Distance",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":53.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x1","reference-y1","x1","y1","width1","height1","fill1","rotation1","x2","width2","fill2","x3","fill3"],
+            "variable":["A.y","text1","reference-x2","reference-y2","y2","height2","text2","fontsize","rotation2","reference-x3","reference-y3","y3","width3","height3","text3","rotation3"],
+            "components":[
+                {
+                  "type":"Group",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":27.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Advanced hun control",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"0",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"79",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":80.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Mentioned hate",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"24",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"94",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":133.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Addressed LGBT community",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"19",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"123",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Text",
+            "level":0,
+            "reference-x":"Left",
+            "reference-y":"Bottom",
+            "x":24.0,
+            "y":912.0,
+            "width":482.0,
+            "height":22.0,
+            "rotation":0.0,
+            "fill":"0x6680e6ff",
+            "text":"Topics Mentioned More by Democrats",
+            "fontsize":20.0,
+            "lock":"false"
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Table",
+            "row":2,
+            "column":0,
+            "nrows":6,
+            "ncolumns":3,
+            "source":"2",
+            "group":"2",
+            "wide":true,
+            "network":false,
+            "properties":["text1","text2","text3"],
+            "variables":[
+                {
+                  "name":"text1",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Topic"],
+                  "function":"text1"
+                },
+                {
+                  "name":"text2",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Rep."],
+                  "function":"text2"
+                },
+                {
+                  "name":"text3",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Dem."],
+                  "function":"text3"
+                }
+              ]
+          },
+          {
+            "type":"Table",
+            "row":11,
+            "column":0,
+            "nrows":6,
+            "ncolumns":3,
+            "source":"1",
+            "group":"1",
+            "wide":true,
+            "network":false,
+            "properties":["A.y","x"],
+            "variables":[
+                {
+                  "name":"A.y",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Topic"],
+                  "mappings":[
+                      {
+                        "from":"28.0",
+                        "to":"Stated support for gun rights"
+                      },
+                      {
+                        "from":"82.0",
+                        "to":"Criticized Obama Administration"
+                      },
+                      {
+                        "from":"136.0",
+                        "to":"Praised first responders"
+                      },
+                      {
+                        "from":"190.0",
+                        "to":"Used phrases similar to radical Islam"
+                      },
+                      {
+                        "from":"244.0",
+                        "to":"Condemned terrorism"
+                      },
+                      {
+                        "from":"298.0",
+                        "to":"Thoughs & Prayers"
+                      }
+                    ]
+                },
+                {
+                  "name":"x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Responders","Responders"],
+                  "function":"x/2"
+                }
+              ]
+          },
+          {
+            "type":"Value",
+            "row":0,
+            "column":0,
+            "nrows":1,
+            "ncolumns":2,
+            "source":"3",
+            "wide":true,
+            "network":false,
+            "properties":["text"],
+            "variables":[
+                {
+                  "name":"text",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Title 1"],
+                  "function":"text"
+                }
+              ]
+          },
+          {
+            "type":"Value",
+            "row":0,
+            "column":0,
+            "nrows":1,
+            "ncolumns":2,
+            "source":"3",
+            "wide":true,
+            "network":false,
+            "properties":["text"],
+            "variables":[
+                {
+                  "name":"text",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Title 1"],
+                  "function":"text"
+                }
+              ]
+          },
+          {
+            "type":"Value",
+            "row":19,
+            "column":0,
+            "nrows":1,
+            "ncolumns":2,
+            "source":"6",
+            "wide":true,
+            "network":false,
+            "properties":["text"],
+            "variables":[
+                {
+                  "name":"text",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Title 2"],
+                  "function":"text"
+                }
+              ]
+          },
+          {
+            "type":"Table",
+            "row":21,
+            "column":0,
+            "nrows":3,
+            "ncolumns":3,
+            "source":"5",
+            "group":"5",
+            "wide":true,
+            "network":false,
+            "properties":["text1","text2","text3"],
+            "variables":[
+                {
+                  "name":"text1",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Topic"],
+                  "function":"text1"
+                },
+                {
+                  "name":"text2",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Rep."],
+                  "function":"text2"
+                },
+                {
+                  "name":"text3",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Dem."],
+                  "function":"text3"
+                }
+              ]
+          },
+          {
+            "type":"Table",
+            "row":26,
+            "column":0,
+            "nrows":3,
+            "ncolumns":3,
+            "source":"4",
+            "group":"4",
+            "wide":true,
+            "network":false,
+            "properties":["A.y","x"],
+            "variables":[
+                {
+                  "name":"A.y",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Topic"],
+                  "mappings":[
+                      {
+                        "from":"26.0",
+                        "to":"Advanced hun control"
+                      },
+                      {
+                        "from":"80.0",
+                        "to":"Mentioned hate"
+                      },
+                      {
+                        "from":"134.0",
+                        "to":"Addressed LGBT community"
+                      }
+                    ]
+                },
+                {
+                  "name":"x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Responders","Responders"],
+                  "function":"x/2"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/republicans-democrats.json b/gallery/republicans-democrats.json
new file mode 100644
index 0000000000000000000000000000000000000000..c6636e230372a0087f9d13958f0052be54479fd2
--- /dev/null
+++ b/gallery/republicans-democrats.json
@@ -0,0 +1,573 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":3,
+        "prefix":"C.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":585.0,
+        "y":773.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.x","B.curve","B.stroke","B.thickness","B.rotation","A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.thickness","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+        "variable":["B.y","A.y","A.stroke","x"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":2,
+              "prefix":"B.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":22.0,
+              "y":0.0,
+              "sticky-y":"Yes",
+              "sticky-x":"No",
+              "distribution-x":"None",
+              "distribution-y":"Distance",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":57.0,
+              "curve":"None",
+              "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["A.y","x"],
+              "components":[
+                  {
+                    "type":"LineChart",
+                    "id":"1.1",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xb3ccffbc",
+                    "x":0.0,
+                    "y":23.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"StraightSolid",
+                    "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                    "variable":["x","fill"],
+                    "components":[
+                        {
+                          "type":"Ellipse",
+                          "id":"1.1.1",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":158.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0x8099ffff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        },
+                        {
+                          "type":"Ellipse",
+                          "id":"1.1.2",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0xe64d4dff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        }
+                      ]
+                  },
+                  {
+                    "type":"LineChart",
+                    "id":"1.2",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xb3ccffbc",
+                    "x":0.0,
+                    "y":80.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"StraightSolid",
+                    "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                    "variable":["x","fill"],
+                    "components":[
+                        {
+                          "type":"Ellipse",
+                          "id":"1.2.1",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":188.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0x8099ffff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        },
+                        {
+                          "type":"Ellipse",
+                          "id":"1.2.2",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":48.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0xe64d4dff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        }
+                      ]
+                  },
+                  {
+                    "type":"LineChart",
+                    "id":"1.3",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xb3ccffbc",
+                    "x":0.0,
+                    "y":137.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"StraightSolid",
+                    "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                    "variable":["x","fill"],
+                    "components":[
+                        {
+                          "type":"Ellipse",
+                          "id":"1.3.1",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":246.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0x8099ffff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        },
+                        {
+                          "type":"Ellipse",
+                          "id":"1.3.2",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":38.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0xe64d4dff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        }
+                      ]
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":2,
+              "prefix":"B.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":22.0,
+              "y":225.0,
+              "sticky-y":"Yes",
+              "sticky-x":"No",
+              "distribution-x":"None",
+              "distribution-y":"Distance",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":57.0,
+              "curve":"None",
+              "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["A.y","x"],
+              "components":[
+                  {
+                    "type":"LineChart",
+                    "id":"2.1",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xe699b345",
+                    "x":0.0,
+                    "y":18.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"StraightSolid",
+                    "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                    "variable":["x","fill"],
+                    "components":[
+                        {
+                          "type":"Ellipse",
+                          "id":"2.1.1",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0x8099ffff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        },
+                        {
+                          "type":"Ellipse",
+                          "id":"2.1.2",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":18.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0xe64d4dff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        }
+                      ]
+                  },
+                  {
+                    "type":"LineChart",
+                    "id":"2.2",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xe699b345",
+                    "x":0.0,
+                    "y":75.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"StraightSolid",
+                    "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                    "variable":["x","fill"],
+                    "components":[
+                        {
+                          "type":"Ellipse",
+                          "id":"2.2.1",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":0.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0x8099ffff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        },
+                        {
+                          "type":"Ellipse",
+                          "id":"2.2.2",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":24.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0xe64d4dff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        }
+                      ]
+                  },
+                  {
+                    "type":"LineChart",
+                    "id":"2.3",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xe699b345",
+                    "x":0.0,
+                    "y":132.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"StraightSolid",
+                    "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                    "variable":["x","fill"],
+                    "components":[
+                        {
+                          "type":"Ellipse",
+                          "id":"2.3.1",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":92.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0x8099ffff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        },
+                        {
+                          "type":"Ellipse",
+                          "id":"2.3.2",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":136.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0xe64d4dff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        }
+                      ]
+                  },
+                  {
+                    "type":"LineChart",
+                    "id":"2.4",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xe699b345",
+                    "x":0.0,
+                    "y":189.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"StraightSolid",
+                    "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                    "variable":["x","fill"],
+                    "components":[
+                        {
+                          "type":"Ellipse",
+                          "id":"2.4.1",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":6.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0x8099ffff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        },
+                        {
+                          "type":"Ellipse",
+                          "id":"2.4.2",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":160.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0xe64d4dff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        }
+                      ]
+                  },
+                  {
+                    "type":"LineChart",
+                    "id":"2.5",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xe699b345",
+                    "x":0.0,
+                    "y":246.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"StraightSolid",
+                    "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                    "variable":["x","fill"],
+                    "components":[
+                        {
+                          "type":"Ellipse",
+                          "id":"2.5.1",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":178.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0x8099ffff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        },
+                        {
+                          "type":"Ellipse",
+                          "id":"2.5.2",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":292.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0xe64d4dff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        }
+                      ]
+                  },
+                  {
+                    "type":"LineChart",
+                    "id":"2.6",
+                    "level":1,
+                    "prefix":"A.",
+                    "thickness":1.5,
+                    "stroke":"0xe699b345",
+                    "x":0.0,
+                    "y":303.0,
+                    "sticky-y":"No",
+                    "sticky-x":"Yes",
+                    "distribution-x":"None",
+                    "distribution-y":"None",
+                    "rotation":0.0,
+                    "delta-x":0.0,
+                    "delta-y":0.0,
+                    "curve":"StraightSolid",
+                    "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                    "variable":["x","fill"],
+                    "components":[
+                        {
+                          "type":"Ellipse",
+                          "id":"2.6.1",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":228.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0x8099ffff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        },
+                        {
+                          "type":"Ellipse",
+                          "id":"2.6.2",
+                          "level":0,
+                          "reference-x":"Center",
+                          "reference-y":"Bottom",
+                          "x":398.0,
+                          "y":0.0,
+                          "width":17.0,
+                          "height":17.0,
+                          "thickness":0.0,
+                          "rotation":0.0,
+                          "fill":"0xe64d4dff",
+                          "stroke":"0x505080ff",
+                          "shape":"Ellipse",
+                          "lock":"true"
+                        }
+                      ]
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/republicans-democrats.wrk b/gallery/republicans-democrats.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..f8442676571419a211e9f211dd15874417338d10
--- /dev/null
+++ b/gallery/republicans-democrats.wrk
@@ -0,0 +1,2801 @@
+{
+  "workspace":    {
+      "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":490.0,
+            "y":937.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+            "variable":["x","y","width","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":125.0,
+                        "y":141.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":88.0,
+                        "y":76.0,
+                        "width":18.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":116.0,
+                        "y":36.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":206.0,
+                        "y":69.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":186.0,
+                        "y":114.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":266.0,
+                        "y":107.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":216.0,
+                        "y":141.0,
+                        "width":14.0,
+                        "height":14.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":300.0,
+                        "y":188.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":30.0,
+                        "y":56.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":67.0,
+                        "y":104.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":126.0,
+                        "y":68.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":164.0,
+                        "y":71.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":147.0,
+                        "y":116.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":257.0,
+                        "y":157.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":311.0,
+                        "y":149.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":237.0,
+                        "y":97.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":1004.0,
+            "y":1228.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":66.0,
+                  "height":62.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":72.0,
+                  "width":75.0,
+                  "height":19.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"my label",
+                  "fontsize":14.0,
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":1004.0,
+            "y":935.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+            "variable":["y","width","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":-72.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":-82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":-89.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":-93.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":-51.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":-26.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":86.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":103.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":125.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":66.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":36.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":9.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":978.0,
+            "y":803.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":-124.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x1","y","stroke","thickness","rotation"],
+            "variable":["width","height","shape","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["y1","y2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":106.0,
+                  "height":106.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff9999ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":78.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":125.0,
+            "y":1120.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":270.5,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":23.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":50.0,
+                        "width":37.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":222.5,
+            "y":1071.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":4.0,
+            "common":["reference-x","reference-y","x","shape","stroke","thickness","rotation"],
+            "variable":["y","width","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["shape1","shape2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":88.0,
+                  "height":12.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffccccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":16.0,
+                  "width":16.0,
+                  "height":91.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3ccffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          }
+        ],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":59.0,
+            "y":997.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":37.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x1","reference-y1","x1","y1","width1","height1","fill1","rotation1","x2","width2","fill2","x3","fill3"],
+            "variable":["A.y","text1","reference-x2","reference-y2","y2","height2","text2","reference-x3","reference-y3","y3","width3","height3","text3","fontsize","rotation2","rotation3"],
+            "components":[
+                {
+                  "type":"Group",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":22.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Stated support for gun rights",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"9",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"0",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":78.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Criticized Obama Administration",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"12",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"0",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":134.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Praised first responders",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"68",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"46",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":190.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Used phrases similar to radical Islam",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"80",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"3",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":246.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Condemned terrorism",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"146",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"89",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"6",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":302.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"6.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Thoughs & Prayers",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"6.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"199",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"6.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"114",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":55.0,
+            "y":772.0,
+            "sticky-y":"Yes",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":37.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.rotation","reference-x1","reference-y1","x1","y1","width1","height1","fill1","rotation1","x2","width2","fill2","x3","fill3"],
+            "variable":["A.y","text1","reference-x2","reference-y2","y2","height2","text2","fontsize","rotation2","reference-x3","reference-y3","y3","width3","height3","text3","rotation3"],
+            "components":[
+                {
+                  "type":"Group",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":25.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3","fontsize","fontsize"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Advanced gun control",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"0",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"79",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":81.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3","fontsize","fontsize"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Mentioned hate",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"24",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"94",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Group",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "x":0.0,
+                  "y":137.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"Spacing",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":10.0,
+                  "delta-y":0.0,
+                  "common":["reference-x","reference-y","y","width","height","fontsize","rotation"],
+                  "variable":["x","text","fill"],
+                  "public":["text1","text2","text3","fontsize","fontsize"],
+                  "bindings":[
+                      ["reference-x1","reference-x2","reference-x3"],
+                      ["reference-y1","reference-y2","reference-y3"],
+                      ["y1","y2","y3"],
+                      ["width1"],
+                      ["width2","width3"],
+                      ["height1","height2","height3"],
+                      ["fontsize","fontsize","fontsize"],
+                      ["rotation1","rotation2","rotation3"]
+                    ],
+                  "components":[
+                      {
+                        "type":"Text",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":368.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x696969ff",
+                        "text":"Addressed LGBT community",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":378.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "text":"19",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Text",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Bottom",
+                        "x":438.0,
+                        "y":0.0,
+                        "width":50.0,
+                        "height":19.0,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "text":"123",
+                        "fontsize":14.0,
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":3,
+            "prefix":"C.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":585.0,
+            "y":773.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["B.sticky-x","B.sticky-y","B.distribution-x","B.delta-x","B.distribution-y","B.delta-y","B.x","B.curve","B.stroke","B.thickness","B.rotation","A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.thickness","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+            "variable":["B.y","A.y","A.stroke","x"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":2,
+                  "prefix":"B.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":22.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Distance",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":57.0,
+                  "curve":"None",
+                  "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["A.y","x"],
+                  "components":[
+                      {
+                        "type":"LineChart",
+                        "id":"1.1",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xb3ccffbc",
+                        "x":0.0,
+                        "y":23.0,
+                        "sticky-y":"No",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"StraightSolid",
+                        "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                        "variable":["x","fill"],
+                        "components":[
+                            {
+                              "type":"Ellipse",
+                              "id":"1.1.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":158.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x8099ffff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Ellipse",
+                              "id":"1.1.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"LineChart",
+                        "id":"1.2",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xb3ccffbc",
+                        "x":0.0,
+                        "y":80.0,
+                        "sticky-y":"No",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"StraightSolid",
+                        "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                        "variable":["x","fill"],
+                        "components":[
+                            {
+                              "type":"Ellipse",
+                              "id":"1.2.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":188.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x8099ffff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Ellipse",
+                              "id":"1.2.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":48.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"LineChart",
+                        "id":"1.3",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xb3ccffbc",
+                        "x":0.0,
+                        "y":137.0,
+                        "sticky-y":"No",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"StraightSolid",
+                        "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                        "variable":["x","fill"],
+                        "components":[
+                            {
+                              "type":"Ellipse",
+                              "id":"1.3.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":246.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x8099ffff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Ellipse",
+                              "id":"1.3.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":38.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            }
+                          ]
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":2,
+                  "prefix":"B.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":22.0,
+                  "y":225.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Distance",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":57.0,
+                  "curve":"None",
+                  "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["A.y","x"],
+                  "components":[
+                      {
+                        "type":"LineChart",
+                        "id":"2.1",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xe699b345",
+                        "x":0.0,
+                        "y":18.0,
+                        "sticky-y":"No",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"StraightSolid",
+                        "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                        "variable":["x","fill"],
+                        "components":[
+                            {
+                              "type":"Ellipse",
+                              "id":"2.1.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x8099ffff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Ellipse",
+                              "id":"2.1.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":18.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"LineChart",
+                        "id":"2.2",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xe699b345",
+                        "x":0.0,
+                        "y":75.0,
+                        "sticky-y":"No",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"StraightSolid",
+                        "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                        "variable":["x","fill"],
+                        "components":[
+                            {
+                              "type":"Ellipse",
+                              "id":"2.2.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":0.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x8099ffff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Ellipse",
+                              "id":"2.2.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":24.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"LineChart",
+                        "id":"2.3",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xe699b345",
+                        "x":0.0,
+                        "y":132.0,
+                        "sticky-y":"No",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"StraightSolid",
+                        "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                        "variable":["x","fill"],
+                        "components":[
+                            {
+                              "type":"Ellipse",
+                              "id":"2.3.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":92.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x8099ffff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Ellipse",
+                              "id":"2.3.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":136.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"LineChart",
+                        "id":"2.4",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xe699b345",
+                        "x":0.0,
+                        "y":189.0,
+                        "sticky-y":"No",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"StraightSolid",
+                        "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                        "variable":["x","fill"],
+                        "components":[
+                            {
+                              "type":"Ellipse",
+                              "id":"2.4.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":6.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x8099ffff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Ellipse",
+                              "id":"2.4.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":160.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"LineChart",
+                        "id":"2.5",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xe699b345",
+                        "x":0.0,
+                        "y":246.0,
+                        "sticky-y":"No",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"StraightSolid",
+                        "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                        "variable":["x","fill"],
+                        "components":[
+                            {
+                              "type":"Ellipse",
+                              "id":"2.5.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":178.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x8099ffff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Ellipse",
+                              "id":"2.5.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":292.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            }
+                          ]
+                      },
+                      {
+                        "type":"LineChart",
+                        "id":"2.6",
+                        "level":1,
+                        "prefix":"A.",
+                        "thickness":1.5,
+                        "stroke":"0xe699b345",
+                        "x":0.0,
+                        "y":303.0,
+                        "sticky-y":"No",
+                        "sticky-x":"Yes",
+                        "distribution-x":"None",
+                        "distribution-y":"None",
+                        "rotation":0.0,
+                        "delta-x":0.0,
+                        "delta-y":0.0,
+                        "curve":"StraightSolid",
+                        "common":["reference-x","reference-y","y","width","height","shape","stroke","thickness","rotation"],
+                        "variable":["x","fill"],
+                        "components":[
+                            {
+                              "type":"Ellipse",
+                              "id":"2.6.1",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":228.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0x8099ffff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            },
+                            {
+                              "type":"Ellipse",
+                              "id":"2.6.2",
+                              "level":0,
+                              "reference-x":"Center",
+                              "reference-y":"Bottom",
+                              "x":398.0,
+                              "y":0.0,
+                              "width":17.0,
+                              "height":17.0,
+                              "thickness":0.0,
+                              "rotation":0.0,
+                              "fill":"0xe64d4dff",
+                              "stroke":"0x505080ff",
+                              "shape":"Ellipse",
+                              "lock":"true"
+                            }
+                          ]
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Text",
+            "level":0,
+            "reference-x":"Left",
+            "reference-y":"Bottom",
+            "x":44.0,
+            "y":1342.0,
+            "width":398.0,
+            "height":23.0,
+            "rotation":0.0,
+            "fill":"0xcc3333ff",
+            "text":"Topics Mentioned More by Republicans",
+            "fontsize":20.0,
+            "lock":"false"
+          },
+          {
+            "type":"Text",
+            "level":0,
+            "reference-x":"Left",
+            "reference-y":"Bottom",
+            "x":40.0,
+            "y":944.0,
+            "width":398.0,
+            "height":23.0,
+            "rotation":0.0,
+            "fill":"0x4d66ccff",
+            "text":"Topics Mentioned More by Democrats",
+            "fontsize":20.0,
+            "lock":"false"
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Value",
+            "row":0,
+            "column":0,
+            "nrows":1,
+            "ncolumns":2,
+            "source":"4",
+            "wide":true,
+            "network":false,
+            "properties":["text"],
+            "variables":[
+                {
+                  "name":"text",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Title 1"],
+                  "function":"text"
+                }
+              ]
+          },
+          {
+            "type":"Table",
+            "row":2,
+            "column":0,
+            "nrows":6,
+            "ncolumns":3,
+            "source":"1",
+            "group":"1",
+            "wide":true,
+            "network":false,
+            "properties":["text1","text2","text3"],
+            "variables":[
+                {
+                  "name":"text1",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Topic"],
+                  "function":"text1"
+                },
+                {
+                  "name":"text2",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Rep."],
+                  "function":"text2"
+                },
+                {
+                  "name":"text3",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Dem."],
+                  "function":"text3"
+                }
+              ]
+          },
+          {
+            "type":"Value",
+            "row":10,
+            "column":0,
+            "nrows":1,
+            "ncolumns":2,
+            "source":"5",
+            "wide":true,
+            "network":false,
+            "properties":["text"],
+            "variables":[
+                {
+                  "name":"text",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Title 2"],
+                  "function":"text"
+                }
+              ]
+          },
+          {
+            "type":"Table",
+            "row":12,
+            "column":0,
+            "nrows":3,
+            "ncolumns":3,
+            "source":"2",
+            "group":"2",
+            "wide":true,
+            "network":false,
+            "properties":["text1","text2","text3"],
+            "variables":[
+                {
+                  "name":"text1",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Topic"],
+                  "function":"text1"
+                },
+                {
+                  "name":"text2",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Rep."],
+                  "function":"text2"
+                },
+                {
+                  "name":"text3",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Dem."],
+                  "function":"text3"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":17,
+            "column":0,
+            "nrows":3,
+            "ncolumns":2,
+            "source":"3.1",
+            "group":"3.1",
+            "wide":true,
+            "network":false,
+            "properties":["x"],
+            "variables":[
+                {
+                  "name":"x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Dem.","Rep."],
+                  "function":"x/2"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":21,
+            "column":0,
+            "nrows":6,
+            "ncolumns":2,
+            "source":"3.2",
+            "group":"3.2",
+            "wide":true,
+            "network":false,
+            "properties":["x"],
+            "variables":[
+                {
+                  "name":"x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Dem.","Rep."],
+                  "function":"x/2"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":14,
+            "column":4,
+            "nrows":18,
+            "ncolumns":1,
+            "source":"3",
+            "group":"3",
+            "wide":false,
+            "network":false,
+            "properties":["x"],
+            "variables":[
+                {
+                  "name":"x",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":true,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Mentions"],
+                  "function":"x/2"
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/gallery/sankey-UK-elections.json b/gallery/sankey-UK-elections.json
new file mode 100644
index 0000000000000000000000000000000000000000..b0ed617bc8902aa36e32fd50742d675427f72319
--- /dev/null
+++ b/gallery/sankey-UK-elections.json
@@ -0,0 +1,270 @@
+{
+  "visualizations":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":98.0,
+        "y":903.5,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+        "variable":["A.x","y","height"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":23.0,
+              "y":14.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":7.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":16.0,
+                    "height":44.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xccccccff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":51.0,
+                    "width":16.0,
+                    "height":10.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xffe666ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":68.0,
+                    "width":16.0,
+                    "height":148.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":223.0,
+                    "width":16.0,
+                    "height":96.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":406.0,
+              "y":14.0,
+              "sticky-y":"Yes",
+              "sticky-x":"Yes",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":7.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":16.0,
+                    "height":42.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xccccccff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":49.0,
+                    "width":16.0,
+                    "height":18.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xffe666ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":74.0,
+                    "width":16.0,
+                    "height":146.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":227.0,
+                    "width":16.0,
+                    "height":92.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e6ff",
+                    "stroke":"0x50508000",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            }
+          ],
+        "fill":"0xaaaabcff",
+        "opacity":0.3253968253968254,
+        "coloring":"Source",
+        "connections":[
+            {
+              "origin":"1.1",
+              "destination":"2.2",
+              "weight":6.3953488372093
+            },
+            {
+              "origin":"1.4",
+              "destination":"2.2",
+              "weight":2.0
+            },
+            {
+              "origin":"1.1",
+              "destination":"2.1",
+              "weight":30.0
+            },
+            {
+              "origin":"1.3",
+              "destination":"2.1",
+              "weight":6.0
+            },
+            {
+              "origin":"1.2",
+              "destination":"2.2",
+              "weight":10.0
+            },
+            {
+              "origin":"1.4",
+              "destination":"2.3",
+              "weight":4.0
+            },
+            {
+              "origin":"1.4",
+              "destination":"2.4",
+              "weight":84.0
+            },
+            {
+              "origin":"1.4",
+              "destination":"2.1",
+              "weight":6.0
+            },
+            {
+              "origin":"1.1",
+              "destination":"2.4",
+              "weight":4.0
+            },
+            {
+              "origin":"1.3",
+              "destination":"2.3",
+              "weight":138.0
+            },
+            {
+              "origin":"1.1",
+              "destination":"2.3",
+              "weight":4.0
+            },
+            {
+              "origin":"1.3",
+              "destination":"2.4",
+              "weight":4.0
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/gallery/sankey-UK-elections.wrk b/gallery/sankey-UK-elections.wrk
new file mode 100644
index 0000000000000000000000000000000000000000..ec69192d9052aa21d51a126b54dad9d5da1d9edb
--- /dev/null
+++ b/gallery/sankey-UK-elections.wrk
@@ -0,0 +1,1681 @@
+{
+  "workspace":    {
+        "library":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":490.0,
+            "y":937.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+            "variable":["x","y","width","height","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":125.0,
+                        "y":141.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":88.0,
+                        "y":76.0,
+                        "width":18.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":116.0,
+                        "y":36.0,
+                        "width":16.0,
+                        "height":16.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":206.0,
+                        "y":69.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":186.0,
+                        "y":114.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":266.0,
+                        "y":107.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":216.0,
+                        "y":141.0,
+                        "width":14.0,
+                        "height":14.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":300.0,
+                        "y":188.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4db1",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"None",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":0.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+                  "variable":["x","y","width","height"],
+                  "components":[
+                      {
+                        "type":"Ellipse",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":30.0,
+                        "y":56.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":67.0,
+                        "y":104.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":126.0,
+                        "y":68.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":164.0,
+                        "y":71.0,
+                        "width":26.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":147.0,
+                        "y":116.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":257.0,
+                        "y":157.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":311.0,
+                        "y":149.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      },
+                      {
+                        "type":"Ellipse",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Center",
+                        "x":237.0,
+                        "y":97.0,
+                        "width":20.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e696",
+                        "stroke":"0x50508000",
+                        "shape":"Ellipse",
+                        "lock":"true"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":1004.0,
+            "y":1228.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":10.0,
+            "common":["reference-x","reference-y","x","rotation"],
+            "variable":["y","width","height","shape","text","fontsize","fill","stroke","thickness"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":66.0,
+                  "height":62.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Text",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":72.0,
+                  "width":75.0,
+                  "height":19.0,
+                  "rotation":0.0,
+                  "fill":"0x696969ff",
+                  "text":"my label",
+                  "fontsize":14.0,
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":1004.0,
+            "y":935.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","height","shape","stroke","thickness","rotation"],
+            "variable":["y","width","fill"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":-72.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":-82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":-89.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":-93.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":-51.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":-39.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":-26.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6b3e6ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":0.0,
+                  "y":0.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":11.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+                  "variable":["y","width"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":30.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":36.0,
+                        "width":86.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":72.0,
+                        "width":82.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":108.0,
+                        "width":103.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.5",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":144.0,
+                        "width":125.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.6",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":180.0,
+                        "width":66.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.7",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":216.0,
+                        "width":36.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.8",
+                        "level":0,
+                        "reference-x":"Left",
+                        "reference-y":"Center",
+                        "x":0.0,
+                        "y":252.0,
+                        "width":9.0,
+                        "height":25.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x99b3ffff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":978.0,
+            "y":803.0,
+            "sticky-y":"Yes",
+            "sticky-x":"Yes",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":-124.0,
+            "delta-y":0.0,
+            "common":["reference-x","reference-y","x1","y","stroke","thickness","rotation"],
+            "variable":["width","height","shape","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["y1","y2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":106.0,
+                  "height":106.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xff9999ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"true"
+                },
+                {
+                  "type":"Ellipse",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Center",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":78.0,
+                  "height":78.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffff66ff",
+                  "stroke":"0x505080ff",
+                  "shape":"Ellipse",
+                  "lock":"false"
+                }
+              ]
+          },
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":125.0,
+            "y":1120.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"Distance",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":57.125,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":42.0,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":49.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":54.0,
+                        "width":37.0,
+                        "height":27.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":86.0,
+                        "width":37.0,
+                        "height":38.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":99.125,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":29.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":34.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":61.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"3",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":156.25,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"3.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":57.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":62.0,
+                        "width":37.0,
+                        "height":20.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"3.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":87.0,
+                        "width":37.0,
+                        "height":37.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"4",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":213.375,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"4.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":47.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":52.0,
+                        "width":37.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"4.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":99.0,
+                        "width":37.0,
+                        "height":54.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"5",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":270.5,
+                  "y":0.0,
+                  "sticky-y":"No",
+                  "sticky-x":"No",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":5.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"5.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":37.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe6ccff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":23.0,
+                        "width":37.0,
+                        "height":22.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe6e699ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"5.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":50.0,
+                        "width":37.0,
+                        "height":26.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x80b380ff",
+                        "stroke":"0x505080ff",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ]
+          },
+          {
+            "type":"Group",
+            "level":1,
+            "prefix":"A.",
+            "x":222.5,
+            "y":1071.0,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"Spacing",
+            "rotation":20.0,
+            "delta-x":0.0,
+            "delta-y":4.0,
+            "common":["reference-x","reference-y","x","shape","stroke","thickness","rotation"],
+            "variable":["y","width","height","fill"],
+            "public":["A.x","A.y"],
+            "bindings":[
+                ["reference-x1","reference-x2"],
+                ["reference-y1","reference-y2"],
+                ["x1","x2"],
+                ["shape1","shape2"],
+                ["stroke1","stroke2"],
+                ["thickness1","thickness2"],
+                ["rotation1","rotation2"]
+              ],
+            "components":[
+                {
+                  "type":"Rectangle",
+                  "id":"1",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":0.0,
+                  "width":88.0,
+                  "height":12.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xffccccff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                },
+                {
+                  "type":"Rectangle",
+                  "id":"2",
+                  "level":0,
+                  "reference-x":"Center",
+                  "reference-y":"Bottom",
+                  "x":0.0,
+                  "y":16.0,
+                  "width":16.0,
+                  "height":91.0,
+                  "thickness":0.5,
+                  "rotation":0.0,
+                  "fill":"0xb3ccffff",
+                  "stroke":"0x505080ff",
+                  "shape":"Rectangle",
+                  "lock":"false"
+                }
+              ]
+          }
+    ],
+      "visualizations":[
+          {
+            "type":"Collection",
+            "level":2,
+            "prefix":"B.",
+            "thickness":1.5,
+            "stroke":"0xd9cccc80",
+            "x":98.0,
+            "y":903.5,
+            "sticky-y":"No",
+            "sticky-x":"No",
+            "distribution-x":"None",
+            "distribution-y":"None",
+            "rotation":0.0,
+            "delta-x":0.0,
+            "delta-y":0.0,
+            "curve":"None",
+            "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+            "variable":["A.x","y","height"],
+            "components":[
+                {
+                  "type":"Collection",
+                  "id":"1",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":23.0,
+                  "y":14.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"1.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":16.0,
+                        "height":44.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xccccccff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":51.0,
+                        "width":16.0,
+                        "height":10.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe666ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":68.0,
+                        "width":16.0,
+                        "height":148.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"1.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":223.0,
+                        "width":16.0,
+                        "height":96.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                },
+                {
+                  "type":"Collection",
+                  "id":"2",
+                  "level":1,
+                  "prefix":"A.",
+                  "thickness":1.5,
+                  "stroke":"0xd9cccc80",
+                  "x":406.0,
+                  "y":14.0,
+                  "sticky-y":"Yes",
+                  "sticky-x":"Yes",
+                  "distribution-x":"None",
+                  "distribution-y":"Spacing",
+                  "rotation":0.0,
+                  "delta-x":0.0,
+                  "delta-y":7.0,
+                  "curve":"None",
+                  "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+                  "variable":["y","height","fill"],
+                  "components":[
+                      {
+                        "type":"Rectangle",
+                        "id":"2.1",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":0.0,
+                        "width":16.0,
+                        "height":42.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xccccccff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.2",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":49.0,
+                        "width":16.0,
+                        "height":18.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xffe666ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.3",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":74.0,
+                        "width":16.0,
+                        "height":146.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0xe64d4dff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      },
+                      {
+                        "type":"Rectangle",
+                        "id":"2.4",
+                        "level":0,
+                        "reference-x":"Center",
+                        "reference-y":"Bottom",
+                        "x":0.0,
+                        "y":227.0,
+                        "width":16.0,
+                        "height":92.0,
+                        "thickness":0.5,
+                        "rotation":0.0,
+                        "fill":"0x6680e6ff",
+                        "stroke":"0x50508000",
+                        "shape":"Rectangle",
+                        "lock":"false"
+                      }
+                    ]
+                }
+              ],
+            "fill":"0xaaaabcff",
+            "opacity":0.3253968253968254,
+            "coloring":"Source",
+            "connections":[
+                {
+                  "origin":"1.1",
+                  "destination":"2.2",
+                  "weight":6.3953488372093
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.2",
+                  "weight":2.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.1",
+                  "weight":30.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.1",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.2",
+                  "destination":"2.2",
+                  "weight":10.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.3",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.4",
+                  "weight":84.0
+                },
+                {
+                  "origin":"1.4",
+                  "destination":"2.1",
+                  "weight":6.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.4",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.3",
+                  "weight":138.0
+                },
+                {
+                  "origin":"1.1",
+                  "destination":"2.3",
+                  "weight":4.0
+                },
+                {
+                  "origin":"1.3",
+                  "destination":"2.4",
+                  "weight":4.0
+                }
+              ]
+          },
+          {
+            "type":"Text",
+            "level":0,
+            "reference-x":"Left",
+            "reference-y":"Bottom",
+            "x":84.0,
+            "y":1283.0,
+            "width":314.0,
+            "height":30.0,
+            "rotation":0.0,
+            "fill":"0x696969ff",
+            "text":"Change in council control",
+            "fontsize":22.0,
+            "lock":"false"
+          }
+        ],
+      "datasheet":[
+          {
+            "type":"Table",
+            "row":1,
+            "column":0,
+            "nrows":12,
+            "ncolumns":3,
+            "source":"1",
+            "group":"1",
+            "wide":true,
+            "network":true,
+            "properties":["id","id","weight"],
+            "variables":[
+                {
+                  "name":"id",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["source","destination"],
+                  "mappings":[
+                      {
+                        "from":"1.1.1",
+                        "to":"No control"
+                      },
+                      {
+                        "from":"1.1.2",
+                        "to":"Lib Dems"
+                      },
+                      {
+                        "from":"1.1.3",
+                        "to":"Labour"
+                      },
+                      {
+                        "from":"1.1.4",
+                        "to":"Conservative"
+                      },
+                      {
+                        "from":"1.2.1",
+                        "to":"No control"
+                      },
+                      {
+                        "from":"1.2.2",
+                        "to":"Lib Dems"
+                      },
+                      {
+                        "from":"1.2.3",
+                        "to":"Labour"
+                      },
+                      {
+                        "from":"1.2.4",
+                        "to":"Conservative"
+                      }
+                    ]
+                },
+                {
+                  "name":"weight",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["Change (seats)"],
+                  "function":"weight/2"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":15,
+            "column":0,
+            "nrows":8,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["id"],
+            "variables":[
+                {
+                  "name":"id",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":false,
+                  "labels":["id"],
+                  "function":"id"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":15,
+            "column":1,
+            "nrows":8,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["height"],
+            "variables":[
+                {
+                  "name":"height",
+                  "type":"Functional",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["Seats"],
+                  "function":"height/2"
+                }
+              ]
+          },
+          {
+            "type":"Column",
+            "row":15,
+            "column":2,
+            "nrows":8,
+            "ncolumns":1,
+            "source":"1",
+            "group":"1",
+            "wide":false,
+            "network":false,
+            "properties":["A.id"],
+            "variables":[
+                {
+                  "name":"A.id",
+                  "type":"Symbolic",
+                  "axis":false,
+                  "axis-outer":false,
+                  "legend":false,
+                  "node":true,
+                  "labels":["When"],
+                  "mappings":[
+                      {
+                        "from":"1.1",
+                        "to":"Before 2018 election"
+                      },
+                      {
+                        "from":"1.2",
+                        "to":"After 2018 election"
+                      }
+                    ]
+                }
+              ]
+          }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/lib/controlsfx-8.40.12-sources/META-INF/MANIFEST.MF b/lib/controlsfx-8.40.12-sources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..58630c02ef423cffd6dd6aafd946eb8512040c37
--- /dev/null
+++ b/lib/controlsfx-8.40.12-sources/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/lib/controlsfx-8.40.12-sources/META-INF/services/org.controlsfx.glyphfont.GlyphFont b/lib/controlsfx-8.40.12-sources/META-INF/services/org.controlsfx.glyphfont.GlyphFont
new file mode 100644
index 0000000000000000000000000000000000000000..1d1eed76422a4f8a82d07ad77ca70ed048b2d1b5
--- /dev/null
+++ b/lib/controlsfx-8.40.12-sources/META-INF/services/org.controlsfx.glyphfont.GlyphFont
@@ -0,0 +1 @@
+org.controlsfx.glyphfont.FontAwesome
\ No newline at end of file
diff --git a/lib/matheclipse-core-1.0.0-SNAPSHOT-jar-with-dependencies.jar b/lib/matheclipse-core-1.0.0-SNAPSHOT-jar-with-dependencies.jar
new file mode 100644
index 0000000000000000000000000000000000000000..37cb8cefa916e9ee55bb8f474ec40035aa60008c
Binary files /dev/null and b/lib/matheclipse-core-1.0.0-SNAPSHOT-jar-with-dependencies.jar differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0ad7dae2e580a28513e7852db7dacddaa81de0d4
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,44 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>Infographer</groupId>
+  <artifactId>Infographer</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <build>
+    <sourceDirectory>src</sourceDirectory>
+    <resources>
+      <resource>
+        <directory>src</directory>
+        <excludes>
+          <exclude>**/*.java</exclude>
+        </excludes>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.7.0</version>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  
+  
+  <dependencies>
+  	<dependency>
+  		<groupId>javax.json</groupId>
+  		<artifactId>javax.json-api</artifactId>
+  		<version>1.0</version>
+  	</dependency>
+  	
+  	<dependency>
+  		<groupId>org.glassfish</groupId>
+  		<artifactId>javax.json</artifactId>
+  		<version>1.0.4</version>
+  	</dependency>
+
+  </dependencies>
+  
+</project>
\ No newline at end of file
diff --git a/sessions/library.json b/sessions/library.json
new file mode 100644
index 0000000000000000000000000000000000000000..b3953ca72d06cfd6a7dbbe5ffa5cc47e67118be1
--- /dev/null
+++ b/sessions/library.json
@@ -0,0 +1,1899 @@
+{
+  "library":[
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":96.875,
+        "y":785.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"Distance",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":57.125,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","x","width","shape","fill","stroke","thickness","rotation"],
+        "variable":["A.x","y","height"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":42.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":5.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":37.0,
+                    "height":49.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xffe6ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":54.0,
+                    "width":37.0,
+                    "height":27.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff9999ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":86.0,
+                    "width":37.0,
+                    "height":38.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":99.125,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":5.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":37.0,
+                    "height":29.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xffe6ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":34.0,
+                    "width":37.0,
+                    "height":22.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff9999ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":61.0,
+                    "width":37.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":156.25,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":5.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":37.0,
+                    "height":57.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xffe6ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":62.0,
+                    "width":37.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff9999ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":87.0,
+                    "width":37.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":213.375,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"None",
+              "distribution-y":"Spacing",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":5.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+              "variable":["y","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":37.0,
+                    "height":47.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xffe6ccff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":52.0,
+                    "width":37.0,
+                    "height":42.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xff9999ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":99.0,
+                    "width":37.0,
+                    "height":54.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4dff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            }
+          ]
+      },
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":90.0,
+        "y":871.0,
+        "sticky-y":"Yes",
+        "sticky-x":"Yes",
+        "distribution-x":"None",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":10.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","shape","stroke","thickness","rotation"],
+        "variable":["x","y","width","height","fill"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y","width","height"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":125.0,
+                    "y":141.0,
+                    "width":26.0,
+                    "height":26.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4db1",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":88.0,
+                    "y":76.0,
+                    "width":18.0,
+                    "height":18.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4db1",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":116.0,
+                    "y":36.0,
+                    "width":16.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4db1",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":206.0,
+                    "y":69.0,
+                    "width":26.0,
+                    "height":26.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4db1",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":186.0,
+                    "y":114.0,
+                    "width":26.0,
+                    "height":26.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4db1",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":266.0,
+                    "y":107.0,
+                    "width":26.0,
+                    "height":26.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4db1",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":216.0,
+                    "y":141.0,
+                    "width":14.0,
+                    "height":14.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4db1",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"1.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":300.0,
+                    "y":188.0,
+                    "width":26.0,
+                    "height":26.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xe64d4db1",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":0.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"None",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":0.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","shape","fill","stroke","thickness","rotation"],
+              "variable":["x","y","width","height"],
+              "components":[
+                  {
+                    "type":"Ellipse",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":30.0,
+                    "y":56.0,
+                    "width":20.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e696",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":67.0,
+                    "y":104.0,
+                    "width":20.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e696",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":126.0,
+                    "y":68.0,
+                    "width":20.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e696",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":164.0,
+                    "y":71.0,
+                    "width":26.0,
+                    "height":26.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e696",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":147.0,
+                    "y":116.0,
+                    "width":20.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e696",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.6",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":257.0,
+                    "y":157.0,
+                    "width":20.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e696",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.7",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":311.0,
+                    "y":149.0,
+                    "width":20.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e696",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  },
+                  {
+                    "type":"Ellipse",
+                    "id":"2.8",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Center",
+                    "x":237.0,
+                    "y":97.0,
+                    "width":20.0,
+                    "height":20.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0x6680e696",
+                    "stroke":"0x50508000",
+                    "shape":"Ellipse",
+                    "lock":"true"
+                  }
+                ]
+            }
+          ]
+      },
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":143.75,
+        "y":808.0,
+        "sticky-y":"No",
+        "sticky-x":"Yes",
+        "distribution-x":"None",
+        "distribution-y":"Distance",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":44.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.x","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+        "variable":["A.y","x","height"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":29.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":50.25,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":21.0,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":71.25,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":121.5,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":171.75,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":222.0,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":29.0,
+              "y":44.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":50.25,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":21.0,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":71.25,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":121.5,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":171.75,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":222.0,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":16.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":29.0,
+              "y":88.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":50.25,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":21.0,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":24.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":71.25,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":24.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":121.5,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":24.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":171.75,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":24.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":222.0,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":24.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":29.0,
+              "y":132.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":50.25,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":21.0,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":71.25,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":121.5,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":171.75,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":222.0,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":30.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"5",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":29.0,
+              "y":176.0,
+              "sticky-y":"No",
+              "sticky-x":"No",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":50.25,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","height","shape","fill","stroke","thickness","rotation"],
+              "variable":["x"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"5.1",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":21.0,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.2",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":71.25,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.3",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":121.5,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.4",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":171.75,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"5.5",
+                    "level":0,
+                    "reference-x":"Center",
+                    "reference-y":"Bottom",
+                    "x":222.0,
+                    "y":0.0,
+                    "width":30.0,
+                    "height":37.0,
+                    "thickness":0.5,
+                    "rotation":0.0,
+                    "fill":"0xcbd7e4ff",
+                    "stroke":"0x505080ff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            }
+          ]
+      },
+      {
+        "type":"Collection",
+        "level":1,
+        "prefix":"A.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":122.0,
+        "y":908.0,
+        "sticky-y":"No",
+        "sticky-x":"Yes",
+        "distribution-x":"Distance",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":29.0,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+        "variable":["x","height","fill"],
+        "components":[
+            {
+              "type":"Rectangle",
+              "id":"1",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":15.0,
+              "y":0.0,
+              "width":28.0,
+              "height":85.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xccccccff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"2",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":44.0,
+              "y":0.0,
+              "width":28.0,
+              "height":129.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0x808080ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"3",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":73.0,
+              "y":0.0,
+              "width":28.0,
+              "height":42.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xe6e64dff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"4",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":102.0,
+              "y":0.0,
+              "width":28.0,
+              "height":68.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0x80b380ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            }
+          ]
+      },
+      {
+        "type":"Group",
+        "level":1,
+        "prefix":"A.",
+        "x":494.0,
+        "y":913.0,
+        "sticky-y":"Yes",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"Spacing",
+        "rotation":20.0,
+        "delta-x":0.0,
+        "delta-y":0.0,
+        "common":["reference-x","reference-y","x","height","shape","fill","stroke","thickness","rotation"],
+        "variable":["y","width"],
+        "public":["A.x","A.y"],
+        "bindings":[
+            ["reference-x1","reference-x2","reference-x3"],
+            ["reference-y1"],
+            ["reference-y2","reference-y3"],
+            ["x1","x2","x3"],
+            ["height1","height3"],
+            ["height2"],
+            ["shape1","shape2","shape3"],
+            ["fill1","fill3"],
+            ["fill2"],
+            ["stroke1","stroke2","stroke3"],
+            ["thickness1","thickness2","thickness3"],
+            ["rotation1","rotation2","rotation3"]
+          ],
+        "components":[
+            {
+              "type":"Rectangle",
+              "id":"1",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Top",
+              "x":0.0,
+              "y":-41.0,
+              "width":92.0,
+              "height":10.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xe6e699ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"2",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":0.0,
+              "y":2.0,
+              "width":13.0,
+              "height":86.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffe6ccff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"3",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":0.0,
+              "y":50.0,
+              "width":55.0,
+              "height":10.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xe6e699ff",
+              "stroke":"0x505080ff",
+              "shape":"Rectangle",
+              "lock":"false"
+            }
+          ]
+      },
+      {
+        "type":"Collection",
+        "level":1,
+        "prefix":"A.",
+        "thickness":1.5,
+        "stroke":"0x808080ff",
+        "x":136.0,
+        "y":972.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["reference-x","reference-y","width","shape","fill","stroke","thickness","rotation"],
+        "variable":["x","y","height"],
+        "components":[
+            {
+              "type":"Rectangle",
+              "id":"1",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":20.0,
+              "y":133.0,
+              "width":25.0,
+              "height":162.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0x8099ffff",
+              "stroke":"0x50508000",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"2",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":106.0,
+              "y":80.0,
+              "width":25.0,
+              "height":81.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0x8099ffff",
+              "stroke":"0x50508000",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"3",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":193.0,
+              "y":206.0,
+              "width":25.0,
+              "height":81.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0x8099ffff",
+              "stroke":"0x50508000",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"4",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":281.0,
+              "y":135.0,
+              "width":25.0,
+              "height":81.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0x8099ffff",
+              "stroke":"0x50508000",
+              "shape":"Rectangle",
+              "lock":"false"
+            },
+            {
+              "type":"Rectangle",
+              "id":"5",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Center",
+              "x":277.0,
+              "y":34.0,
+              "width":25.0,
+              "height":49.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0x8099ffff",
+              "stroke":"0x50508000",
+              "shape":"Rectangle",
+              "lock":"false"
+            }
+          ],
+        "fill":"0xcce6ffff",
+        "opacity":0.3015873015873016,
+        "coloring":"Source",
+        "connections":[
+            {
+              "origin":"1",
+              "destination":"2",
+              "weight":81.0
+            },
+            {
+              "origin":"3",
+              "destination":"4",
+              "weight":81.0
+            },
+            {
+              "origin":"1",
+              "destination":"3",
+              "weight":81.0
+            },
+            {
+              "origin":"2",
+              "destination":"5",
+              "weight":49.0
+            }
+          ]
+      },
+      {
+        "type":"Collection",
+        "level":1,
+        "prefix":"A.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":107.125,
+        "y":3.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"None",
+        "distribution-y":"Spacing",
+        "rotation":0.0,
+        "delta-x":0.0,
+        "delta-y":5.0,
+        "curve":"None",
+        "common":["reference-x","reference-y","x","width","shape","stroke","thickness","rotation"],
+        "variable":["y","height","fill"],
+        "components":[
+            {
+              "type":"Ellipse",
+              "id":"1",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":0.0,
+              "y":0.0,
+              "width":37.0,
+              "height":29.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffe6ccff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"2",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":0.0,
+              "y":34.0,
+              "width":37.0,
+              "height":22.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xff9999ff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            },
+            {
+              "type":"Ellipse",
+              "id":"3",
+              "level":0,
+              "reference-x":"Center",
+              "reference-y":"Bottom",
+              "x":0.0,
+              "y":61.0,
+              "width":37.0,
+              "height":37.0,
+              "thickness":0.5,
+              "rotation":0.0,
+              "fill":"0xffcc66ff",
+              "stroke":"0x505080ff",
+              "shape":"Ellipse",
+              "lock":"false"
+            }
+          ]
+      },
+      {
+        "type":"Collection",
+        "level":2,
+        "prefix":"B.",
+        "thickness":1.5,
+        "stroke":"0xd9cccc80",
+        "x":114.0,
+        "y":996.0,
+        "sticky-y":"No",
+        "sticky-x":"No",
+        "distribution-x":"Distance",
+        "distribution-y":"None",
+        "rotation":0.0,
+        "delta-x":222.0,
+        "delta-y":0.0,
+        "curve":"None",
+        "common":["A.sticky-x","A.sticky-y","A.distribution-x","A.delta-x","A.distribution-y","A.delta-y","A.y","A.curve","A.stroke","A.thickness","A.rotation","reference-x","reference-y","y","width","shape","fill","stroke","thickness","rotation"],
+        "variable":["A.x","x","height"],
+        "components":[
+            {
+              "type":"Collection",
+              "id":"1",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":25.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":56.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"1.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":-48.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":56.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":90.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3ccffff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"1.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":112.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":180.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"2",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":247.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":56.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"2.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":-24.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":56.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":90.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3ccffff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"2.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":112.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":150.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"3",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":469.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":56.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"3.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":-24.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":56.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":36.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3ccffff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"3.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":112.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":42.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            },
+            {
+              "type":"Collection",
+              "id":"4",
+              "level":1,
+              "prefix":"A.",
+              "thickness":1.5,
+              "stroke":"0xd9cccc80",
+              "x":691.0,
+              "y":0.0,
+              "sticky-y":"No",
+              "sticky-x":"Yes",
+              "distribution-x":"Distance",
+              "distribution-y":"None",
+              "rotation":0.0,
+              "delta-x":56.0,
+              "delta-y":0.0,
+              "curve":"None",
+              "common":["reference-x","reference-y","y","width","shape","stroke","thickness","rotation"],
+              "variable":["x","height","fill"],
+              "components":[
+                  {
+                    "type":"Rectangle",
+                    "id":"4.1",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":0.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":-12.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x4d66ccff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.2",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":56.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":90.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0xb3ccffff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  },
+                  {
+                    "type":"Rectangle",
+                    "id":"4.3",
+                    "level":0,
+                    "reference-x":"Left",
+                    "reference-y":"Bottom",
+                    "x":112.0,
+                    "y":0.0,
+                    "width":56.0,
+                    "height":210.0,
+                    "thickness":0.0,
+                    "rotation":0.0,
+                    "fill":"0x8099ffff",
+                    "stroke":"0xffffffff",
+                    "shape":"Rectangle",
+                    "lock":"false"
+                  }
+                ]
+            }
+          ]
+      }
+    ]
+}
\ No newline at end of file
diff --git a/src/controlsfx.properties b/src/controlsfx.properties
new file mode 100644
index 0000000000000000000000000000000000000000..1e7b0c289a4f053149f4b4a4d96be8d0042e3320
--- /dev/null
+++ b/src/controlsfx.properties
@@ -0,0 +1,78 @@
+### Dialogs ###
+
+dlg.ok.button = OK
+dlg.cancel.button = Cancel
+dlg.yes.button = Yes
+dlg.no.button = No
+dlg.close.button = Close
+dlg.detail.button.more = Show Details
+dlg.detail.button.less = Hide Details
+
+### Common Dialogs ###
+
+font.dlg.title=Select font
+font.dlg.header=Select font
+font.dlg.sample.text=Sample
+font.dlg.font.label=Font
+font.dlg.style.label=Style
+font.dlg.size.label=Size
+
+progress.dlg.title=Progress
+progress.dlg.header=Progress
+
+login.dlg.title=Login
+login.dlg.header=Enter user name and password
+login.dlg.user.caption=User Name
+login.dlg.pswd.caption=Password
+login.dlg.login.button=Login
+
+exception.dlg.title = Exception Details
+exception.dlg.header = Exception Details
+exception.dlg.label = The exception stacktrace was:
+exception.button.label = Open Exception
+
+### Wizard ###
+
+wizard.next.button = Next
+wizard.previous.button = Previous
+
+### Property Sheet ###
+
+bean.property.change.error.title = Property Change Error
+bean.property.change.error.header = Change is not allowed
+bean.property.category.basic=Basic
+bean.property.category.expert=Expert
+
+property.sheet.search.field.prompt = Search
+property.sheet.group.mode.byname = By Name
+property.sheet.group.mode.bycategory = By Category
+
+### Spreadsheet View ###
+
+spreadsheet.view.menu.axis = Show on axis
+spreadsheet.view.menu.parentaxis = Show on parent axis
+spreadsheet.view.menu.legend = Show on legend
+spreadsheet.view.menu.node = Show on marks
+
+spreadsheet.view.menu.copy = Copy
+spreadsheet.view.menu.paste = Paste
+spreadsheet.view.menu.comment = Comment cell
+spreadsheet.view.menu.comment.top-left = top left
+spreadsheet.view.menu.comment.top-right = top right
+spreadsheet.view.menu.comment.bottom-right = bottom right
+spreadsheet.view.menu.comment.bottom-left = bottom left
+spreadsheet.column.menu.fix = Fix column
+spreadsheet.column.menu.unfix = Unfix column
+spreadsheet.verticalheader.menu.fix = Fix row
+spreadsheet.verticalheader.menu.unfix = Unfix row
+
+### Status Bar ###
+statusbar.ok = OK
+
+### List Selection View ###
+listSelectionView.header.source = Available
+listSelectionView.header.target = Selected
+
+### PopOver ###
+popOver.default.content = <No Content>
+popOver.default.title = Info
\ No newline at end of file
diff --git a/src/fr/inria/structgraphics/.Rhistory b/src/fr/inria/structgraphics/.Rhistory
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/fr/inria/structgraphics/VisSketcher.java b/src/fr/inria/structgraphics/VisSketcher.java
new file mode 100644
index 0000000000000000000000000000000000000000..c52e328bc5a838681abeeaf016d2b6c0cd23ad2b
--- /dev/null
+++ b/src/fr/inria/structgraphics/VisSketcher.java
@@ -0,0 +1,117 @@
+package fr.inria.structgraphics;
+	
+import fr.inria.structgraphics.graphics.MarkFactory;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.ui.DisplayPreferences;
+import fr.inria.structgraphics.ui.DragManager;
+import fr.inria.structgraphics.ui.inspector.InspectorView;
+import fr.inria.structgraphics.ui.inspector.util.TooltipCreator;
+import fr.inria.structgraphics.ui.spreadsheet.DataView;
+import fr.inria.structgraphics.ui.viscanvas.Canvas;
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import javafx.application.Application;
+import javafx.beans.binding.Bindings;
+
+import javafx.stage.Stage;
+import javafx.scene.Scene;
+import javafx.scene.SceneAntialiasing;
+import javafx.scene.control.ScrollPane;
+
+public class VisSketcher extends Application {
+
+	@Override
+	public void start(Stage stage) {
+		double width = 800, height = 780;
+		
+		VisFrame frame = MarkFactory.createVisFrame(DisplayPreferences.CANVAS_WIDTH, DisplayPreferences.CANVAS_HEIGHT);
+		frame.initProperties();
+		
+		try {
+			CanvasFrame canvasFrame = new CanvasFrame(stage);	
+			Canvas canvas = canvasFrame.getCanvas();
+			
+			ScrollPane scroller = new ScrollPane();
+			scroller.setContent(canvas);
+			canvasFrame.setSketchArea(scroller);
+			
+			canvas.minWidthProperty().bind(Bindings.createDoubleBinding(() -> 
+	        	scroller.getViewportBounds().getWidth(), scroller.viewportBoundsProperty()));
+			
+			canvasFrame.setVisFrame(frame);
+			//canvas.setContent(frame.getGroup());
+
+			
+			// TODO: Fix scrolling
+			//canvasFrame.setCenter(scroller);
+			
+			Scene scene = new Scene(canvasFrame, width, height, false, SceneAntialiasing.BALANCED);
+			scene.getStylesheets().addAll(getClass().getResource("application.css").toExternalForm(), CanvasFrame.STYLESHEETS);
+			
+			stage.setTitle("StructGraphics: Visualization Sketcher");
+			stage.setScene(scene);
+			stage.setX(100);
+			stage.show();
+			
+			// This is the inspector window
+			InspectorView inspector = new InspectorView();
+			DragManager.create(inspector);
+			
+			inspector.setVisualizationFrame(frame);
+			
+			scene = new Scene(inspector, 600, height);
+			scene.getStylesheets().addAll(InspectorView.STYLESHEETS);
+		    Stage inspectStage = new Stage();
+		    inspectStage.setTitle("StructGraphics: Inspector");
+            inspectStage.setScene(scene);
+            inspectStage.setX(stage.getX() + stage.getWidth() + 10);
+            inspectStage.setY(stage.getY());
+            inspectStage.show();
+			            
+            inspector.update();
+			            
+			// The data view
+			DataView dataview = new DataView(inspector);
+			scene = new Scene(dataview, 600, height);
+			scene.getStylesheets().add(DataView.STYLESHEETS);
+			
+			Stage dataStage = new Stage();
+			dataStage.setTitle("StructGraphics: Spreadsheet");
+			dataStage.setScene(scene);
+			dataStage.setX(inspectStage.getX() + inspectStage.getWidth() + 10);
+            dataStage.setY(inspectStage.getY());
+            dataStage.show();
+            
+            /*
+		    LibraryStage libraryStage = new LibraryStage(canvasFrame);
+		    libraryStage.setX(stage.getX() - libraryStage.getWidth() - 5);
+		    libraryStage.setY(stage.getY());*/
+            		    
+            stage.setOnCloseRequest( event -> {canvasFrame.close(); inspectStage.close(); dataStage.close();});
+            inspectStage.setOnCloseRequest( event -> {canvasFrame.close(); stage.close(); dataStage.close();});
+            dataStage.setOnCloseRequest( event -> {canvasFrame.close(); stage.close(); inspectStage.close();});           
+
+			// TODO: temporarry for study purposes
+			//stage.setOnCloseRequest(e->e.consume());
+			//inspectStage.setOnCloseRequest(e->e.consume());
+			//dataStage.setOnCloseRequest(e->e.consume());
+            
+            
+            canvasFrame.setViews( inspector, dataview);
+			canvasFrame.setMenubars(stage, inspectStage);
+			
+			TooltipCreator.hackTooltipStartTiming();
+			
+			
+
+
+		} catch(Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public static void main(String[] args) {				
+		launch(args);
+	}
+	
+
+}
diff --git a/src/fr/inria/structgraphics/application.css b/src/fr/inria/structgraphics/application.css
new file mode 100644
index 0000000000000000000000000000000000000000..83d6f3343843c65d5dfaf3fedb97b6494c19113d
--- /dev/null
+++ b/src/fr/inria/structgraphics/application.css
@@ -0,0 +1 @@
+/* JavaFX CSS - Leave this comment until you have at least create one rule which uses -fx-Property */
\ No newline at end of file
diff --git a/src/fr/inria/structgraphics/graphics/Arrow.java b/src/fr/inria/structgraphics/graphics/Arrow.java
new file mode 100644
index 0000000000000000000000000000000000000000..a4509e5eebc4315f980771a3846646095a45b2bc
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/Arrow.java
@@ -0,0 +1,156 @@
+package fr.inria.structgraphics.graphics;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.property.DoubleProperty;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Shape;
+
+public class Arrow extends Group {
+
+    private final Line line;
+
+    public Arrow() {
+        this(new Line(), new Line(), new Line());
+    }
+
+    private static final double arrowLength = 6;
+    private static final double arrowWidth = 5;
+
+    private Arrow(Line line, Line arrow1, Line arrow2) {
+        super(line, arrow1, arrow2);
+        this.line = line;
+        InvalidationListener updater = o -> {
+            double ex = getEndX();
+            double ey = getEndY();
+            double sx = getStartX();
+            double sy = getStartY();
+            
+            arrow1.setEndX(ex);
+            arrow1.setEndY(ey);
+            arrow2.setEndX(ex);
+            arrow2.setEndY(ey);
+            
+            if(Math.abs(ex - sx) < 8 && Math.abs(ey - sy) < 8) {
+                arrow1.setStartX(ex);
+                arrow1.setStartY(ey);
+                arrow2.setStartX(ex);
+                arrow2.setStartY(ey);
+            	return;
+            }
+            
+
+            if (ex == sx && ey == sy) {
+                // arrow parts of length 0
+                arrow1.setStartX(ex);
+                arrow1.setStartY(ey);
+                arrow2.setStartX(ex);
+                arrow2.setStartY(ey);
+            } else {
+                double factor = arrowLength / Math.hypot(sx-ex, sy-ey);
+                double factorO = arrowWidth / Math.hypot(sx-ex, sy-ey);
+
+                // part in direction of main line
+                double dx = (sx - ex) * factor;
+                double dy = (sy - ey) * factor;
+
+                // part ortogonal to main line
+                double ox = (sx - ex) * factorO;
+                double oy = (sy - ey) * factorO;
+
+                arrow1.setStartX(ex + dx - oy);
+                arrow1.setStartY(ey + dy + ox);
+                arrow2.setStartX(ex + dx + oy);
+                arrow2.setStartY(ey + dy - ox);
+            }
+        };
+
+        // add updater to properties
+        startXProperty().addListener(updater);
+        startYProperty().addListener(updater);
+        endXProperty().addListener(updater);
+        endYProperty().addListener(updater);
+        updater.invalidated(null);
+    }
+
+    
+    public Arrow getCopie(double dx, double dy) {
+    	Arrow arrow = new Arrow();
+    	arrow.setEnds(line.getStartX() + dx, line.getEndX() + dx, line.getStartY() + dy, line.getEndY() + dy);
+    	
+    	return arrow;
+    }
+    
+    // start/end properties
+
+    public final void setEnds(double x1, double x2, double y1, double y2) {    	
+    	line.setStartX(x1);
+    	line.setStartY(y1);
+    	
+    	line.setEndX(x2);
+    	line.setEndY(y2);
+    }
+    
+    
+    public final void setStartX(double value) {
+        line.setStartX(value);
+    }
+
+    public final double getStartX() {
+        return line.getStartX();
+    }
+
+    public final DoubleProperty startXProperty() {
+        return line.startXProperty();
+    }
+
+    public final void setStartY(double value) {
+        line.setStartY(value);
+    }
+
+    public final double getStartY() {
+        return line.getStartY();
+    }
+
+    public final DoubleProperty startYProperty() {
+        return line.startYProperty();
+    }
+
+    public final void setEndX(double value) {
+        line.setEndX(value);
+    }
+
+    public final double getEndX() {
+        return line.getEndX();
+    }
+
+    public final DoubleProperty endXProperty() {
+        return line.endXProperty();
+    }
+
+    public final void setEndY(double value) {
+        line.setEndY(value);
+    }
+
+    public final double getEndY() {
+        return line.getEndY();
+    }
+
+    public final DoubleProperty endYProperty() {
+        return line.endYProperty();
+    }
+
+	public void setStroke(Paint paint) {
+		for(Node shape: getChildren()) {
+			if(shape instanceof Shape) ((Shape)shape).setStroke(paint);
+		}
+	}
+
+	public void setStrokeWidth(double border) {
+		for(Node shape: getChildren()) {
+			if(shape instanceof Shape) ((Shape)shape).setStrokeWidth(border);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/fr/inria/structgraphics/graphics/ComplexShape.java b/src/fr/inria/structgraphics/graphics/ComplexShape.java
new file mode 100644
index 0000000000000000000000000000000000000000..5be7868ff7d921e96570346b16e23ab852370ae2
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/ComplexShape.java
@@ -0,0 +1,106 @@
+package fr.inria.structgraphics.graphics;
+
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Shape;
+
+public class ComplexShape extends Group {
+	
+	// Create a ghost for highlighting the shape 
+	//TODO: ...
+	protected Group ghost; 
+	private boolean highlighted = false;
+	
+	public ComplexShape() {
+		super();
+		
+		ghost = new Group();
+		getChildren().add(ghost);
+		ghost.setVisible(false);
+	}
+
+	public void setFill(Paint paint) {
+		for(Node shape: getChildren()) {
+			if(shape instanceof Shape) ((Shape)shape).setFill(paint);
+		}
+	}
+
+	public void setStroke(Paint paint) {
+		for(Node shape: getChildren()) {
+			if(shape instanceof Shape) ((Shape)shape).setStroke(paint);
+		}
+	}
+
+	public void setStrokeWidth(double border) {
+		for(Node shape: getChildren()) {
+			if(shape instanceof Shape) ((Shape)shape).setStrokeWidth(border);
+		}
+	}
+
+	public void clear() { // TODO
+		getChildren().remove(1, getChildren().size());
+		ghost.getChildren().clear();		
+	}
+	
+	public void add(Shape shape) { 
+		getChildren().add(0, shape);
+		shape.setSmooth(true);
+		//if(highlighted) addToGhost(shape);
+	}
+	
+	public void remove(Shape shape) {
+		getChildren().remove(shape);
+	}
+	
+	public void replaceBy(Shape shape) {
+		getChildren().remove(0);
+		add(shape);
+	}
+
+	public boolean intersects(Shape trace) {
+		if(trace == null) return false;
+		for(Node shape: getChildren()) {
+			if(shape instanceof Shape) {
+				Shape intersection = Shape.intersect((Shape) shape, trace);			
+				if(!(intersection instanceof Path) || !((Path)intersection).getElements().isEmpty()) 
+					return true;
+			}
+		}
+		
+		return false;
+	}
+
+		
+	public void addToGhost(Group group) {
+		for(Node node: group.getChildren()) {
+			Shape shape = (Shape)node;	
+			shape.setStroke( Color.CORNFLOWERBLUE);
+			shape.setFill(null);
+			shape.setStrokeWidth(shape.getStrokeWidth() + 1.5);
+		}
+		
+		ghost.getChildren().addAll(group.getChildren());
+	}
+	
+	public void addToGhost(Shape shape) {
+		ghost.getChildren().add(shape);	
+		shape.setStroke( Color.CORNFLOWERBLUE);
+		shape.setFill(null);
+		shape.setStrokeWidth(shape.getStrokeWidth() + 1.5);
+	}	
+		
+	public void setHighlight(boolean highlight) { 
+		if(highlight && !highlighted) {
+			highlighted = true;
+			ghost.setVisible(true);
+		} else if(!highlight && highlighted) {
+			highlighted = false;
+			ghost.setVisible(false);
+		}
+	}
+
+	
+}
diff --git a/src/fr/inria/structgraphics/graphics/ConnectedCollection.java b/src/fr/inria/structgraphics/graphics/ConnectedCollection.java
new file mode 100644
index 0000000000000000000000000000000000000000..799f5238dd6633c42817a5e41cb8f4de1d0e9316
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/ConnectedCollection.java
@@ -0,0 +1,200 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.google.common.io.LineProcessor;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.AlignmentProperty.XSticky;
+import fr.inria.structgraphics.types.AlignmentProperty.YSticky;
+import fr.inria.structgraphics.ui.tools.MarkSelection;
+import fr.inria.structgraphics.ui.tools.SelectFilter;
+import fr.inria.structgraphics.ui.viscanvas.groupings.CollectionPropertyStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupings.ReferenceStructureCreator;
+import fr.inria.structgraphics.ui.viscanvas.groupings.XReferenceStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupings.YReferenceStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupings.Grouping.Type;
+import javafx.beans.Observable;
+import javafx.beans.property.Property;
+import javafx.collections.ObservableList;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Shape;
+
+public abstract class ConnectedCollection extends VisCollection {
+	protected Shape primitif;
+	protected Shape ghost;
+
+	protected boolean curveSelected = false;
+	
+	public ConnectedCollection(Container parent, boolean toend) {
+		super(parent, toend);	
+	}
+		
+	
+	public ConnectedCollection(Container parent, boolean toend, ObservableList<Mark> marks) {
+		super(parent, toend);	
+		
+		ReferenceStructureCreator creator = new ReferenceStructureCreator(marks, Type.Collection);
+		XReferenceStructure xstruct = creator.getXReferenceStructure();
+		YReferenceStructure ystruct = creator.getYReferenceStructure();
+		
+		setLevel(marks.get(0).getLevel() + 1); // TODO: To remove???
+		ReferenceCoords refCoords = new ReferenceCoords(RefX.Left, RefY.Bottom);
+		setRefCoords(refCoords);
+
+		getConstraintXProperty().set(xstruct.constraint);
+		getConstraintYProperty().set(ystruct.constraint);
+		
+		PositionCoords coords = new PositionCoords(this, xstruct.getRefValue(), ystruct.getRefValue());
+		setCoords(coords);
+		
+		for(Mark mark: marks) {
+			mark.getCoords().xRef.set(xstruct.getRef());
+			mark.getCoords().yRef.set(ystruct.getRef());
+			attach(mark, xstruct.isShared(), ystruct.isShared());
+		}
+		
+		refresh();
+		
+		CollectionPropertyStructure propertyStructure = new CollectionPropertyStructure(marks);
+		setPropertyStructure(propertyStructure);
+				
+		initProperties();
+				
+	//	initializeShape();
+	}	
+		
+	public boolean isCurveSelected() {
+		return curveSelected;
+	}
+	
+	public boolean isSingleSibling() {
+		if(!(container instanceof VisCollection) || 
+				((VisCollection)container).alignXProperty.get() == YSticky.No &&
+				((VisCollection)container).alignYProperty.get() == XSticky.No)
+			return true;
+		else return false;
+	}
+	
+	
+	@Override
+	public void initProperties() {		
+		border.set(1.5);
+		addProperty(border);
+		addProperty(strokePaint);
+		
+		super.initProperties();		
+	}
+	
+
+	@Override
+	protected void updateBasicShape() {
+		labels.update();
+		refreshShape();
+		updateGhost();
+	}
+	
+	protected abstract Shape createShape();
+	protected abstract void refreshShape();
+	
+		
+	/*
+	@Override
+	public boolean monoselect(MarkSelection selectedMarks, Circle trace) { // To review how to prioritize its selection or not...			
+		
+		curveSelected = false;
+
+		boolean consumed = super.monoselect(selectedMarks, trace);
+		if(consumed) {
+			return consumed;
+		}
+		
+		if(shape.intersects(trace) && components.size() > 0) { 
+			pinX = components.get(0).coords.getX();
+			pinY = components.get(0).coords.getY();
+				
+			selectedMarks.add(this);
+	
+			curveSelected = true;
+					
+			return true;
+		}
+
+		return false;
+	}*/
+	
+	@Override
+	public void pin() {
+		if(!curveSelected) super.pin();
+	}
+	
+
+	@Override
+	public void select(MarkSelection selectedMarks, Shape trace, SelectFilter filter) {
+		curveSelected = false;
+		super.select(selectedMarks, trace, filter);
+	}	
+	
+	
+	@Override
+	public boolean controlselect(MarkSelection selectedMarks, Circle trace) {	
+		curveSelected = false;
+		return super.controlselect(selectedMarks, trace);
+	}
+	
+	
+	@Override
+	public void setHighlight(boolean highlight, boolean enableControllers) {
+		super.setHighlight(highlight, enableControllers);
+		shape.setHighlight(highlight);
+	}
+	
+	
+	@Override
+	public void translate(Line lineTrace) {
+		if(!curveSelected) {
+			super.translate(lineTrace);
+		}
+		else if(components.size() > 0){		
+			double x = pinX + lineTrace.getEndX() - lineTrace.getStartX() - components.get(0).coords.getX();
+			double y = pinY - lineTrace.getEndY() + lineTrace.getStartY() - components.get(0).coords.getY();
+			
+			if(childPropertyStructure.isXShared()) {
+				Mark mark = components.get(0);
+				mark.coords.x.set(x + mark.coords.getX());
+			} else for(Mark mark: components) {
+				mark.coords.x.set(x + mark.coords.getX());
+			}
+
+			if(childPropertyStructure.isYShared()) {
+				Mark mark = components.get(0);
+				mark.coords.y.set(y + mark.coords.getY());
+			} else for(Mark mark: components) {
+				mark.coords.y.set(y + mark.coords.getY());
+			}
+			
+			updateInteractor();
+			//updateBasicShape();
+		}
+	}
+	
+	@Override
+	public void invalidated(Observable observable) {
+		super.invalidated(observable);
+		updateBasicShape();
+	}
+	
+	@Override
+	public Map<PropertyName, Property> getSelfProperties() {
+		Map<PropertyName, Property> map = new TreeMap<>();
+		for(Property property: properties) map.put(new PropertyName(property.getName()), property);
+		return map;
+	}
+		
+	protected abstract Shape primitifCopy(double dx, double dy, boolean shadow); 
+}
diff --git a/src/fr/inria/structgraphics/graphics/Container.java b/src/fr/inria/structgraphics/graphics/Container.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f006af77ca2b82743f85e2c44a9eeb02ab2bc4e
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/Container.java
@@ -0,0 +1,297 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.sun.prism.image.Coords;
+
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.IdentifierProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import fr.inria.structgraphics.ui.tools.MarkSelection;
+import fr.inria.structgraphics.ui.tools.SelectFilter;
+import fr.inria.structgraphics.ui.viscanvas.groupings.CollectionPropertyStructure;
+import javafx.beans.property.Property;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.geometry.Point2D;
+import javafx.scene.Group;
+import javafx.scene.control.TextField;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Shape;
+
+public abstract class Container {	
+	
+	protected List<Mark> components = new ArrayList<Mark>();
+	protected Group group  = new Group();
+	protected List<Property> properties = new ArrayList<Property>();
+	protected Map<PropertyName, FlexibleListProperty> tabularProperties = null; // TODO: Not currently used. To remove?
+	
+	protected ReferenceCoords refCoords;
+	
+	public StringProperty id;
+			
+	protected final ChangeListener changeListener = new ChangeListener() {
+		@Override
+		public void changed(ObservableValue observable, Object oldValue, Object newValue) {
+			update();
+		}
+	};
+	
+	public Container() {
+		createIdProperty();
+	}
+		
+	protected void createIdProperty() {
+		id = new IdentifierProperty(this, "id");
+	}
+	
+	public void refreshID() {
+		for(Mark mark:components)
+			mark.refreshID();
+	}
+	
+	// TODO: To change....
+	public void addProperty(Property property) {
+		property.addListener(changeListener);
+		properties.add(property);
+	}
+	
+	public void removeProperty(Property property) { // TODO: I will probably need to also remove it (if needed from )
+		property.removeListener(changeListener);
+		properties.remove(property);
+	}
+	
+	public void addPropertiesColumn(FlexibleListProperty property) {
+		if(tabularProperties == null) tabularProperties = new TreeMap<>();
+		
+		tabularProperties.put(new PropertyName(property.getName()), property); // TODO: To add change listeners!!!
+		
+		property.addListener(changeListener);
+		for(Property p:property) p.addListener(changeListener);
+	}
+	
+	
+	public boolean hasTabularProperties() {
+		return tabularProperties != null;
+	}
+	
+	/*
+	 * Check is the mark should be added to the end of the childrent or not. By default it is true
+	 */
+	public boolean addToEnd(double x, double y) {
+		return true;
+	}
+	
+	public void setRefCoords(ReferenceCoords coords) {
+		this.refCoords = coords;
+	}
+	
+	public ReferenceCoords getRefCoords() {
+		return refCoords;
+	}
+	
+	public VisBody getRootVirtualGroup() {
+		return null;
+	}
+	
+	public VisBody getVirtualGroup() {
+		return null;
+	}
+	
+	public int leafs() {
+		if(components == null || components.size() == 0) return 1;
+		
+		int counter = 0; 
+		for(Mark mark:components) {
+			counter += mark.leafs();
+		}
+		
+		return counter;
+	}
+	
+	public void update() { 
+		updateProperties();
+		updateAll();
+	}
+	
+	public void initProperties() {
+		if(refCoords != null) {			
+			addProperty(refCoords.getContainerXRefProperty());
+			addProperty(refCoords.getContainerYRefProperty());
+		}
+	}
+	
+	public void updateProperties() {
+		// empty
+	}
+	
+	public void addMark(Mark mark, boolean toend){
+		mark.container = this;
+		
+		if(toend) {
+			components.add(mark);
+			group.getChildren().add(mark.group);
+		}
+		else {
+			components.add(0, mark);
+			group.getChildren().add(0, mark.group);
+		}		
+		
+		refreshID();
+	}
+		
+	public void removeMark(Mark mark) {
+		components.remove(mark); 
+		refreshID();
+	}
+	
+	public Group getGroup(){
+		return group;
+	}
+			
+	protected void updateAll() {
+		clear();
+		updateShape();
+		
+		for(Container component: components)
+			component.updateAll();
+	}
+	
+	public void clear() {
+		group.getTransforms().clear();
+	}
+	
+	public List<Property> getProperties(){
+		return properties;
+	}
+	
+	public Map<PropertyName, Property> getSelfProperties() {
+		Map<PropertyName, Property> map = new TreeMap<>();
+		for(Property property: properties) map.put(new PropertyName(property.getName()), property);
+		return map;
+	}
+	
+	public Map<PropertyName, FlexibleListProperty> getTabularProperties(){
+		return tabularProperties;
+	}
+
+	public void addLeafIDs(List<Property> ids){
+		for(Mark mark:components)
+			mark.addLeafIDs(ids);
+	}
+	
+	public void addIDs(List<Property> ids, int level) {
+		for(Mark mark:components)
+			mark.addIDs(ids, level);
+	}
+	
+	public List<Mark> getComponents(){
+		return components;
+	}
+	
+	public Mark getComponentAt(int i){
+		return components.get(i);
+	}
+	
+	public Container getComponent(String sid){
+		for(Mark component: components) {
+			Container mark = component.getComponent(sid);
+			if(mark != null) return mark;
+		}
+		
+		return null;
+	}
+	
+	public abstract void updateShape();
+	// protected abstract Point2D getReferencePoint(double cx, double cy, RefX containerXRef, RefY containerYRef);
+	public abstract Point2D getReferencePoint(double cx, double cy);
+	public abstract double getRefAngle(double x);
+	
+	public Point2D getOffsetPoint() {
+		return getReferencePoint(0, 0);
+	}
+	
+	// protected abstract double getRefAngle(double x, RefX containerXRef);
+
+	public abstract String getName();
+	public abstract String getType();
+	
+			
+	public void select(MarkSelection selectedMarks, Shape trace, SelectFilter filter) {
+		for(Mark mark: components)
+			mark.select(selectedMarks, trace, filter);
+	}
+	
+	public boolean monoselect(MarkSelection selectedMarks, Circle trace) {
+		for(int i = components.size() - 1; i >=0; --i) {
+			if(((Mark)components.get(i)).controlselect(selectedMarks, trace)) return true;
+		}
+		
+		for(int i = components.size() - 1; i >=0; --i) {
+			if(((Mark)components.get(i)).monoselect(selectedMarks, trace)) return true;
+		}
+		
+		return false;
+	}
+
+	
+	public ShapeMark getShape(double x, double y) {
+		for(Mark mark: components) {
+			double x_ = x - mark.coords.getX();
+			double y_ = y - mark.coords.getY();
+			
+			ShapeMark mark_ = mark.getShape(x_, y_);
+			if(mark_ != null) return mark_;
+		}
+				
+		return null;
+	}
+	
+	
+	public double getRootWidth() {
+		return 0;
+	}
+	
+	public double getRootHeight() {
+		return 0;
+	}
+
+
+	public void addTextField(TextField textField, boolean add) {
+		if(add) group.getChildren().add(textField);
+		else group.getChildren().remove(textField);
+	}
+	
+	public void showGroupInteractors(boolean show) {
+		for(Mark mark:components)
+			mark.showGroupInteractors(show);
+	}
+
+	
+	public void bringToFront(Mark mark) {}
+
+	public void sendToBack(Mark mark) {}
+	
+	public void updateReordering() {}
+	
+	
+	public boolean hasConnections() {
+		return false;
+	}
+
+	
+	public double getYIn(Container container) {
+		return 0;
+	}
+	
+	public double getXIn(Container container) {
+		return 0;
+	}
+}
+
diff --git a/src/fr/inria/structgraphics/graphics/Fill.java b/src/fr/inria/structgraphics/graphics/Fill.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a9afce4b20459e93c51c2b699ed40d33fe25d44
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/Fill.java
@@ -0,0 +1,27 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+
+public class Fill {
+
+	private final static Fill singleton = new Fill();
+
+	private Map<String, Paint> mapping; 
+	
+	private Fill() {
+		mapping = new TreeMap<String, Paint>();
+		mapping.put("empty", Color.WHITE);
+		mapping.put("pattern1", Color.LIGHTGRAY);
+		mapping.put("pattern2", Color.GRAY);
+		mapping.put("pattern3", Color.DARKGRAY);		
+	}
+	
+	
+	public static Paint getPaint(String name) {
+		return singleton.mapping.get(name);
+	}
+}
diff --git a/src/fr/inria/structgraphics/graphics/FlowCreator.java b/src/fr/inria/structgraphics/graphics/FlowCreator.java
new file mode 100644
index 0000000000000000000000000000000000000000..50a77dd6efd166a6401eac17a4588bbaa9080062
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/FlowCreator.java
@@ -0,0 +1,140 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.splines.CubicSpline;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnection;
+import javafx.geometry.Point2D;
+import javafx.scene.shape.CubicCurveTo;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+
+public class FlowCreator {
+	private static final double defaultArrowHeadSize = 8.0;
+
+	public static void createCurve(Path path, FlowConnection flowConnection) {
+		double dx;
+		
+		if(flowConnection.startX() < flowConnection.endX()) dx = Math.min(50, (flowConnection.endX() - flowConnection.startX())/3);
+		else dx = Math.max(-50, (flowConnection.endX() - flowConnection.startX())/3);
+			
+		MoveTo moveTo = new MoveTo();
+		moveTo.setX(flowConnection.startX());
+		moveTo.setY(flowConnection.startY());
+
+		CubicCurveTo cubicTo = new CubicCurveTo();
+		cubicTo.setControlX1(flowConnection.startX() + dx);
+		cubicTo.setControlY1(flowConnection.startY());
+		cubicTo.setControlX2(flowConnection.endX() - dx);
+		cubicTo.setControlY2(flowConnection.endY());
+		cubicTo.setX(flowConnection.endX());
+		cubicTo.setY(flowConnection.endY());
+
+		path.getElements().add(moveTo);
+		path.getElements().add(cubicTo);
+	}
+	
+	public static void createFlowConnectionPath(FlowPath path, FlowConnection flowConnection) {
+		double dx;
+		
+		if(flowConnection.startX() < flowConnection.endX()) dx = Math.min(50, (flowConnection.endX() - flowConnection.startX())/3);
+		else dx = Math.max(-50, (flowConnection.endX() - flowConnection.startX())/3);
+		
+		double bottom1 = flowConnection.startYBottom();
+		double bottom2 = flowConnection.endYBottom();
+		
+		double y1 = bottom1 + flowConnection.getOrigin().getOriginFlag();
+		double y2 = y1 + flowConnection.weightProperty().get();
+				
+		double y4 = bottom2 + flowConnection.getDestination().getDestinationFlag();
+		double y3 = y4 + flowConnection.weightProperty().get();
+				
+		double x1 = flowConnection.startX();
+		double x2 = flowConnection.endX();
+		
+		path.setY1(y1, y2);
+		path.setY2(y4, y3);
+		path.setX(x1, x2);
+
+		MoveTo moveTo = new MoveTo();
+		moveTo.setX(x1);
+		moveTo.setY(y1);
+
+		LineTo lineTo = new LineTo();
+		lineTo.setX(x1);
+		lineTo.setY(y2);
+		
+		CubicCurveTo cubicTo = new CubicCurveTo();
+		cubicTo.setControlX1(x1 + dx);
+		cubicTo.setControlY1(y2);
+		cubicTo.setControlX2(x2 - dx);
+		cubicTo.setControlY2(y3);
+		cubicTo.setX(x2);
+		cubicTo.setY(y3);
+
+		LineTo lineTo2 = new LineTo();
+		lineTo2.setX(x2);
+		lineTo2.setY(y4);
+				
+		CubicCurveTo cubicTo2 = new CubicCurveTo();
+		cubicTo2.setControlX1(x2 - dx);
+		cubicTo2.setControlY1(y4);
+		cubicTo2.setControlX2(x1 + dx);
+		cubicTo2.setControlY2(y1);
+		cubicTo2.setX(x1);
+		cubicTo2.setY(y1);
+		
+		path.getElements().add(moveTo);
+		path.getElements().add(lineTo);
+		path.getElements().add(cubicTo);
+		path.getElements().add(lineTo2);
+		path.getElements().add(cubicTo2);
+		
+		flowConnection.getOrigin().increaseOriginFlag(flowConnection.weightProperty().get());
+		flowConnection.getDestination().increaseDestinationFlag(flowConnection.weightProperty().get());
+	}
+	
+	public static void createLine(Path path, FlowConnection flowConnection) {
+		MoveTo moveTo = new MoveTo();
+		moveTo.setX(flowConnection.startX());
+		moveTo.setY(flowConnection.startY());
+		path.getElements().add(moveTo);
+		
+		LineTo lineTo = new LineTo();
+		lineTo.setX(flowConnection.endX());
+		lineTo.setY(flowConnection.endY());
+		path.getElements().add(lineTo);
+	}
+	
+	public static void createArrow(Path path, FlowConnection flowConnection) {
+		double startX = flowConnection.startX();
+		double startY = flowConnection.startY();
+		double endX = flowConnection.endX();
+		double endY = flowConnection.endY();
+		
+	      //Line
+		path.getElements().add(new MoveTo(startX, startY));
+		path.getElements().add(new LineTo(endX, endY));
+        
+        //ArrowHead
+        double angle = Math.atan2((endY - startY), (endX - startX)) - Math.PI / 2.0;
+        double sin = Math.sin(angle);
+        double cos = Math.cos(angle);
+        //point1
+        double x1 = (- 1.0 / 2.0 * cos + Math.sqrt(3) / 2 * sin) * defaultArrowHeadSize + endX;
+        double y1 = (- 1.0 / 2.0 * sin - Math.sqrt(3) / 2 * cos) * defaultArrowHeadSize  + endY;
+        //point2
+        double x2 = (1.0 / 2.0 * cos + Math.sqrt(3) / 2 * sin) * defaultArrowHeadSize  + endX;
+        double y2 = (1.0 / 2.0 * sin - Math.sqrt(3) / 2 * cos) * defaultArrowHeadSize  + endY;
+        
+        path.getElements().add(new LineTo(x1, y1));
+        path.getElements().add(new LineTo(x2, y2));
+        path.getElements().add(new LineTo(endX, endY));
+        
+        path.setStrokeWidth(flowConnection.weightProperty().get());
+	}
+
+
+}
diff --git a/src/fr/inria/structgraphics/graphics/FlowPath.java b/src/fr/inria/structgraphics/graphics/FlowPath.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e581465fd8720caebd5a7b6d2a9de4531382bc0
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/FlowPath.java
@@ -0,0 +1,34 @@
+package fr.inria.structgraphics.graphics;
+
+import javafx.scene.shape.Path;
+
+public class FlowPath extends Path {
+	private double y1bottom, y1top, y2bottom, y2top;
+	private double left, right;
+	
+	public void setY1(double bottom, double top) {
+		y1bottom = bottom;
+		y1top = top;
+	}
+
+	public void setY2(double bottom, double top) {
+		y2bottom = bottom;
+		y2top = top;
+	}
+	
+	public void setX(double left, double right) {
+		this.left = left;
+		this.right = right;
+	}
+	
+	public double centerY() {
+		//return (y1bottom + y2top)/2;
+		
+		return (2*y1bottom + y2top)/3;
+	}
+	
+	public double centerX() {
+		//return (left + right)/2;
+		return (2*left + right)/3;
+	}
+}
diff --git a/src/fr/inria/structgraphics/graphics/GenericCurve.java b/src/fr/inria/structgraphics/graphics/GenericCurve.java
new file mode 100644
index 0000000000000000000000000000000000000000..0bc0068a9e3b9c43a6630e53ffa2176da1d49e29
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/GenericCurve.java
@@ -0,0 +1,142 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.ArrayList;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.graphics.splines.FlattenedPath;
+import fr.inria.structgraphics.types.DoubleListProperty;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.geometry.Point2D;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Shape;
+import javafx.scene.transform.Rotate;
+
+public abstract class GenericCurve extends Mark  {
+	
+	protected double width = 0, height = 0;
+	protected double length = 0;
+	protected Point2D center; // central point with respect to the first point of the curve
+	
+	protected FlexibleListProperty original_xs = new DoubleListProperty(this, "x");
+	protected FlexibleListProperty original_ys = new DoubleListProperty(this, "y");
+
+	protected ArrayList<Point2D> points;
+	protected Shape path;
+	protected FlattenedPath flattenedPath;
+	
+	protected Point2D middle;
+
+	public GenericCurve(Container parent) {
+		super(parent);		
+	}
+	
+	public GenericCurve(Container parent, ArrayList<Point2D> points){
+		super(parent);
+		
+		for(Point2D p: points) {
+			original_xs.get().add(new SimpleDoubleProperty(p.getX()));
+			original_ys.get().add(new SimpleDoubleProperty(p.getY()));
+		}
+	}
+	
+	@Override
+	public void initProperties() {			
+		super.initProperties();
+				
+		addProperty(angle);
+		addProperty(border);
+		addProperty(strokePaint);
+		
+		addPropertiesColumn(original_xs);
+		addPropertiesColumn(original_ys);
+	}
+	
+	public void addPoint(double x, double y) {		
+		original_xs.get().add(new SimpleDoubleProperty(x));
+		original_ys.get().add(new SimpleDoubleProperty(y));
+	}
+	
+	public Point2D getStart() {
+		return points.get(0);
+	}
+	
+	public Point2D getEnd() {
+		return points.get(points.size() - 1);
+	}
+	
+	public Point2D getMiddle() {
+		return middle;
+	}
+	
+	public double width() {
+		return width;
+	}
+	
+	public double height() {
+		return height;
+	}
+	
+	@Override
+	public void updateShape() {	// TODO: This probably needs some refreshing...
+		points = new ArrayList<Point2D>();
+		///////////////////
+		for(int i = 0; i < original_xs.get().size(); ++i) {
+			double x =  (double)original_xs.get().get(i).getValue();
+			double y =  (double)original_ys.get().get(i).getValue();
+			
+			double cx = x + coords.getX(), cy = y + coords.getY();				
+			points.add(container.getReferencePoint(cx, cy));
+		}
+				
+		updateBasicShape();
+		calculateLength();
+		middle = getPoint(length/2, 0);
+					
+		// TODO: check this angle rotation (with respect to the center???)
+		if(angle.get() != 0) group.getTransforms().add(new Rotate(angle.get(), center.getX(), center.getY()));
+		
+//		if(paint != null) shape.setFill(paint.get());
+//		else shape.setFill(null);
+		
+		if(strokePaint != null) shape.setStroke(strokePaint.get());
+		else shape.setStroke(Color.DARKGRAY);
+		
+		shape.setStrokeWidth(border.get());
+
+	}
+	
+	protected abstract void calculateLength();
+	
+	protected double transformX(double cx, RefX containerXRef) {
+		// X coordinate with respect to the left end (start point) of the curve
+		if(containerXRef == RefX.Left) return cx; 
+		else if(containerXRef == RefX.Right) return length + cx; 
+		else return length/2 + cx;
+	}
+	
+	/*
+	 * It transforms to global coordinates
+	 */
+	@Override
+	public Point2D getReferencePoint(double cx, double cy) {		
+		Point2D p = getPoint(transformX(cx, refCoords.containerXRef.get()), cy);
+//		Point2D center = getCenter();	
+		return new Point2D(p.getX() /*- center.getX()*/, p.getY() /*- center.getY()*/);
+	}
+	
+	@Override
+	public Point2D getOffsetPoint() {
+		return new Point2D(transformX(0, refCoords.containerXRef.get()), 0);
+	}
+	
+	protected Point2D getCenter() {
+		return center;
+	}
+	
+	/* Point at l, y with respect to the first point of the curve
+	 *  
+	 */
+	protected abstract Point2D getPoint(double l, double y);
+}
diff --git a/src/fr/inria/structgraphics/graphics/GenericShapeMark.java b/src/fr/inria/structgraphics/graphics/GenericShapeMark.java
new file mode 100644
index 0000000000000000000000000000000000000000..8fb7bea629f8ed7194720cacc23e5e63c7c22663
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/GenericShapeMark.java
@@ -0,0 +1,143 @@
+package fr.inria.structgraphics.graphics;
+
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.types.ShapeProperty.Type;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.shape.Ellipse;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.shape.Shape;
+
+public class GenericShapeMark extends ShapeMark  {
+
+	protected GenericShapeMark(Container parent,  boolean toend, ShapeProperty.Type type, double w, double h){
+		super(parent, toend, type, w, h);	
+		
+	}
+	
+	@Override
+	public void initProperties() {
+		super.initProperties();
+		
+		properties.add(shapeProperty);
+		shapeProperty.addListener(new ChangeListener<ShapeProperty.Type>() {
+			@Override
+			public void changed(ObservableValue<? extends Type> observable, Type oldValue, Type newValue) {
+				changeShape(newValue);
+			}
+		});	
+	}
+	
+	private void changeShape(Type newShape) {
+		primitif = createShape();
+		shape.replaceBy(primitif);
+		update();
+	}
+	
+	@Override
+	protected Shape createShape() {
+		switch(shapeProperty.get()) {
+			case Ellipse:
+				return new Ellipse(0, 0, Math.abs(width.get()/2), Math.abs(height.get()/2));
+			case Rectangle: 
+				return new Rectangle(-Math.abs(width.get())/2, -Math.abs(height.get())/2, Math.abs(width.get()), Math.abs(height.get()));
+			case Triangle:
+				Path path = new Path();
+				createTriangle(path, width.get(), height.get());
+				return path;
+			case Line:
+				return new Line(-width.get()/2, -height.get()/2, width.get()/2, height.get()/2);
+				
+			default: return null;
+		}
+	} 
+
+	@Override
+	protected void refreshShape() {
+		switch(shapeProperty.get()) {
+			case Ellipse:
+				Ellipse ellipse = (Ellipse)primitif;
+				ellipse.radiusXProperty().set(Math.abs(width.get()/2));
+				ellipse.radiusYProperty().set(Math.abs(height.get()/2));
+				break;
+				
+			case Rectangle: 
+				Rectangle rect = (Rectangle)primitif;
+				rect.xProperty().set(-Math.abs(width.get())/2); 
+				rect.yProperty().set(-Math.abs(height.get())/2);
+				rect.widthProperty().set(Math.abs(width.get()));
+				rect.heightProperty().set(Math.abs(height.get()));
+				break;
+
+			case Triangle:
+				Path path = (Path)primitif;
+				path.getElements().clear();
+				createTriangle(path, width.get(), height.get());
+				break;
+			
+			case Line:
+								
+				Line line = (Line)primitif;			
+				line.startXProperty().set(-width.get()/2); 
+				line.startYProperty().set(-height.get()/2);
+				line.endXProperty().set(width.get()/2);
+				line.endYProperty().set(height.get()/2);
+			
+			default:
+		}
+	}
+	
+			
+	private void createTriangle(Path path, double w, double h) {
+		MoveTo moveTo = new MoveTo();
+		moveTo.setX(0.0);
+		moveTo.setY(-h/2);
+		path.getElements().add(moveTo);
+		
+		LineTo lineTo = new LineTo();
+		lineTo.setX(Math.abs(w)/2);
+		lineTo.setY(h/2);
+		path.getElements().add(lineTo);
+		
+		lineTo = new LineTo();
+		lineTo.setX(-Math.abs(w)/2);
+		lineTo.setY(h/2);
+		path.getElements().add(lineTo);
+		
+		lineTo = new LineTo();
+		lineTo.setX(Math.abs(0));
+		lineTo.setY(-h/2);
+		path.getElements().add(lineTo);
+	}
+	
+	@Override
+	public String getName() {
+		return shapeProperty.get().name();
+	}
+
+	@Override
+	public String getType() {
+		return shapeProperty.get().name();	}
+				
+	
+	@Override
+	public Shadow getShadow(double dx, double dy, double delta) {
+		dx *= delta;
+		dy *= delta;
+		
+		switch(shapeProperty.get()) {
+			case Ellipse:
+				return new Shadow(this, dx, dy, new Ellipse(dx, dy, Math.abs(width.get()/2), Math.abs(height.get()/2))); 
+			case Line:
+				return new Shadow(this, dx, dy, new Line(dx-width.get()/2, dy-height.get()/2, dx + width.get()/2, dy + height.get()/2)); 
+			default: 
+				return new Shadow(this, dx, dy, new Rectangle(dx-Math.abs(width.get())/2, dy-Math.abs(height.get())/2, 
+					Math.abs(width.get()), Math.abs(height.get()))); // TODO: ???
+		}		
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/graphics/HierarchyPos.java b/src/fr/inria/structgraphics/graphics/HierarchyPos.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac37da8eda4caf26467eb9cbecf9d8325400e919
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/HierarchyPos.java
@@ -0,0 +1,33 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.TreeMap;
+
+public class HierarchyPos extends TreeMap<Integer, Integer>{
+	
+	private Mark mark;
+	
+	public HierarchyPos(Mark mark) {
+		super();
+		this.mark = mark;		
+		
+		if(mark.getContainer() instanceof VisBody) {
+			put(mark.level, mark.getContainer().getComponents().indexOf(mark));
+			goUp((VisBody)mark.getContainer());
+		}
+	}
+
+	public void goUp(VisBody mark) {
+		if(mark.getContainer() instanceof VisBody) {
+			put(mark.level, mark.getContainer().getComponents().indexOf(mark));
+			goUp((VisBody)mark.getContainer());
+		}
+	}
+	
+	public int getBottomLevel() {
+		return mark.level;
+	}
+
+	public Integer getIndexAt(int level) {
+		return get(level);
+	}	
+}
diff --git a/src/fr/inria/structgraphics/graphics/LineConnectedCollection.java b/src/fr/inria/structgraphics/graphics/LineConnectedCollection.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e93e09e27c59983f3fa118a53465e306295c0e6
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/LineConnectedCollection.java
@@ -0,0 +1,911 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.graphics.splines.CubicSpline;
+import fr.inria.structgraphics.types.ColoringSchemeProperty;
+import fr.inria.structgraphics.types.FillColorProperty;
+import fr.inria.structgraphics.types.LineTypeProperty;
+import fr.inria.structgraphics.types.OpacityProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.ColoringSchemeProperty.Scheme;
+import fr.inria.structgraphics.types.LineTypeProperty.Type;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import fr.inria.structgraphics.ui.tools.MarkSelection;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnection;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnections;
+import fr.inria.structgraphics.ui.viscanvas.groupings.PropertyStructure;
+import javafx.beans.property.Property;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ObservableList;
+import javafx.geometry.Point2D;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.ClosePath;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Shape;
+import javafx.scene.text.Font;
+import javafx.scene.text.Text;
+import javafx.scene.text.TextAlignment;
+
+public class LineConnectedCollection extends ConnectedCollection {
+	
+	private FlowConnections flowConnections;
+	public LineTypeProperty lineProperty;
+	
+	protected Map<FlowConnection, FlowPath> connectionShapes = new Hashtable<>();
+	protected Map<FlowConnection, Text> connectionLabels = new Hashtable<>();
+	protected FlowConnection connectionSelected = null;
+	protected DataVariable activeVariable;
+	
+//	public StrokeWidthProperty  = new StrokeWidthProperty(this, 0);
+	public FillColorProperty flowPaint = new FillColorProperty (this, Color.rgb(140, 140, 158));
+	public OpacityProperty flowOpacity = new OpacityProperty(this, 0.5);
+	public ColoringSchemeProperty coloringScheme = new ColoringSchemeProperty(this, Scheme.Common);
+		
+	public LineConnectedCollection(Container parent, boolean toend) {
+		super(parent, toend);
+	}	
+	
+	public LineConnectedCollection(Container parent, boolean toend, ObservableList<Mark> marks) {
+		super(parent, toend, marks);
+	
+	}	
+	
+	@Override
+	public void initProperties() {			
+		super.initProperties();
+		
+		//if(flowPaint != null) flowPaint.set(Color.rgb(170, 170, 188));
+		
+		if(lineProperty == null) {
+			lineProperty = new LineTypeProperty(this, LineTypeProperty.Type.None);
+			border.getActiveProperty().set(false);
+			strokePaint.getActiveProperty().set(false);
+		}
+		properties.add(lineProperty);
+		
+		if(lineProperty.get() == LineTypeProperty.Type.TopBottom) {
+			bringConnectionsFront();
+		}
+		
+		lineProperty.addListener(new ChangeListener<LineTypeProperty.Type>() {
+			@Override
+			public void changed(ObservableValue<? extends LineTypeProperty.Type> observable, LineTypeProperty.Type oldValue, LineTypeProperty.Type newValue) {
+				if(newValue != LineTypeProperty.Type.None) reorderChildren(true);
+				changeShape(newValue);
+				
+				if(newValue == LineTypeProperty.Type.None) {
+					border.getActiveProperty().set(false);
+					strokePaint.getActiveProperty().set(false);
+					sendConnectionsBack();
+				} else if(newValue == LineTypeProperty.Type.Straight || newValue == LineTypeProperty.Type.Bezier 
+						|| newValue == LineTypeProperty.Type.TopBottom) {
+					border.getActiveProperty().set(true);
+					strokePaint.getActiveProperty().set(true);
+					
+					if(newValue == LineTypeProperty.Type.TopBottom) {
+						bringConnectionsFront();
+					} else {
+						sendConnectionsBack();
+					}
+					
+				} else {
+					border.getActiveProperty().set(false);
+					strokePaint.getActiveProperty().set(true);
+					//strokePaint.set(Color.color(.85, .8, .8, .5));	
+					sendConnectionsBack();
+				}
+			}
+		});
+		
+		if(lineProperty.get() == LineTypeProperty.Type.StraightSolid || lineProperty.get() == LineTypeProperty.Type.BezierSolid || lineProperty.get() == LineTypeProperty.Type.Area) {
+			paint.bind(strokePaint);
+		} else if(flowConnections != null) {
+			strokePaint = null;
+			paint = null;
+		}
+		else paint.set(null);
+		
+		initializeShape();
+		
+		if(coloringScheme != null) {
+			coloringScheme.addListener(new ChangeListener<Scheme>() {
+				@Override
+				public void changed(ObservableValue<? extends Scheme> observable, Scheme oldValue, Scheme newValue) {
+					
+					updateFlowColoring();
+					flowPaint.getActiveProperty().set(newValue == Scheme.Common);
+				}
+			});			
+		}
+	}
+	
+	private void sendConnectionsBack() {
+		group.getChildren().remove(shape);
+		int index = group.getChildren().indexOf(shapes);
+		group.getChildren().add(index, shape);
+	}
+	
+	private void bringConnectionsFront() {
+		group.getChildren().remove(shape);
+		int index = group.getChildren().indexOf(shapes);
+		group.getChildren().add(index + 1, shape);
+	}
+		
+	@Override
+	public String getName() {
+		String name;
+		if(lineProperty.get() == LineTypeProperty.Type.None) name = "Collection";
+		else if(lineProperty.get() == LineTypeProperty.Type.Area) name = "Area Chart";
+		else name = "Line Chart";
+		
+		return PropertyName.getPrefix(level) + " " + name;
+	}
+
+	@Override
+	public String getType() {
+		if(lineProperty.get() == LineTypeProperty.Type.None) return "Collection";
+		else if(lineProperty.get() == LineTypeProperty.Type.Area) return "AreaChart";
+		else return "LineChart";
+	}
+	
+	
+	protected void initializeShape() {
+		primitif = createShape();
+		shape.add(primitif);	
+		
+		ghost = primitifCopy(0, 0, true);
+		shape.addToGhost(ghost);
+				
+		updateConnections();
+			
+		initControls();		
+	}
+	
+	@Override
+	protected Shape createShape() {
+		Path path = new Path();
+		
+		switch(lineProperty.get()) {
+			case StraightSolid:
+				updateSolidLine(path, 0, 0);
+				break;
+			case Bezier:
+				updateBezier(path, 0, 0);
+				break;
+			case BezierSolid:
+				updateSolidBezier(path, 0, 0);
+				break;
+			case Straight:
+				updatePolyline(path, 0, 0);
+				break;
+			case TopBottom:
+				updateTopBottom(path, 0, 0);
+				break;
+			case Area:
+				updateArea(path, 0, 0);
+				break;
+		}
+		
+		return path;
+	}
+	
+	
+	protected boolean updateConnections() {
+		if(flowConnections == null) return false;
+
+		Collection<FlowConnection> toremove= null;
+		for(FlowConnection flowConnection : connectionShapes.keySet()) {			
+			if(!flowConnections.contains(flowConnection)) {
+				if(toremove == null) toremove = new ArrayList<>();
+				toremove.add(flowConnection);
+				shape.remove(connectionShapes.get(flowConnection));
+			}
+		}		
+		if(toremove != null) {
+			for(FlowConnection conn: toremove) {
+				connectionShapes.remove(conn);
+			}
+			
+			toremove.clear();
+		}			
+						
+		for(FlowConnection flowConnection: flowConnections) {
+			flowConnection.getOrigin().resetConnectionFlags();
+			flowConnection.getDestination().resetConnectionFlags();			
+		}
+		
+		Set<FlowConnection> sorted = flowConnections.sortByY();
+		for(FlowConnection flowConnection: sorted) {
+			FlowPath path;
+			
+			if(!connectionShapes.keySet().contains(flowConnection)) {
+				path = new FlowPath();
+				connectionShapes.put(flowConnection, path);
+				shape.add(path);
+				
+				FillColorProperty paintProperty = getFlowPaint(flowConnection);
+				path.fillProperty().bind(paintProperty);
+				path.strokeProperty().bind(paintProperty);
+				path.opacityProperty().bind(flowOpacity);
+			} else {
+				path = connectionShapes.get(flowConnection);
+				path.getElements().clear();
+			}
+			
+			FlowCreator.createFlowConnectionPath(path, flowConnection);
+		}
+		
+		updateLabels();
+		
+		return true;
+	}
+	
+	
+	protected Font labelFont = Font.font("Verdana", 10);
+	protected Color textColor = Color.GREY;
+	
+	public void addLabel(FlowConnection flowConnection) {
+		final Text text = new Text();
+		text.setFont(labelFont);
+		text.setFill(textColor);
+		text.setTextAlignment(TextAlignment.CENTER);
+		text.setText(flowConnection.weight.get()+"");
+		
+		if(activeVariable != null && activeVariable.nodeShownProperty.get()) {
+			text.setVisible(true);
+			text.textProperty().set(activeVariable.transformationProperty().get().toData(flowConnection.weight.get()));
+		} else text.setVisible(false);
+				
+		connectionLabels.put(flowConnection, text);
+		shape.add(text);
+	}
+	
+	public void removeLabel(FlowConnection flowConnection) {
+		shape.remove(connectionLabels.get(flowConnection));
+		connectionLabels.remove(flowConnection);
+	}
+	
+	public void updateLabels() {
+
+		for(FlowConnection flowConnection: flowConnections) {
+			Text label = connectionLabels.get(flowConnection);
+			FlowPath path = connectionShapes.get(flowConnection);
+			
+			label.xProperty().set(path.centerX() - label.getLayoutBounds().getWidth()/2);
+			label.yProperty().set(path.centerY() + label.getLayoutBounds().getHeight()/2);
+			
+			if(activeVariable != null) label.textProperty().set(activeVariable.transformationProperty().get().toData(flowConnection.weight.get()));
+		}
+	}
+	
+	// Displays the labels for all flow connections
+	public void showLabels(DataVariable variable) {
+		activeVariable = variable;
+		
+		for(FlowConnection flowConnection: flowConnections) {
+			Text label = connectionLabels.get(flowConnection);
+			label.setVisible(variable.nodeShownProperty.get());			
+		}	
+		
+		if(activeVariable.nodeShownProperty.get()) updateLabels();
+	}
+	
+
+	private void updateFlowColoring() {
+		for(FlowConnection flowConnection: flowConnections) {
+			Shape path = connectionShapes.get(flowConnection);
+			FillColorProperty paintProperty = getFlowPaint(flowConnection);
+			
+			if(connectionSelected == flowConnection) { 
+				path.fillProperty().unbind(); 
+				
+				paintProperty = new FillColorProperty(this, ((Color)paintProperty.get()).darker());
+				path.fillProperty().bind(paintProperty);
+			}
+			else {
+				path.fillProperty().unbind();
+				path.strokeProperty().unbind();
+				path.fillProperty().bind(paintProperty);
+				path.strokeProperty().bind(paintProperty);				
+			}
+		}	
+	}
+	
+	private FillColorProperty getFlowPaint(FlowConnection connection) {
+		if(coloringScheme.get() == Scheme.Destination) return connection.getDestination().paint;
+		else if(coloringScheme.get() == Scheme.Source) return connection.getOrigin().paint;
+		return flowPaint;
+	}
+	
+	
+	@Override
+	public void updateGhost() { // TODO:....
+		if(ghost == null) return;
+		
+		switch(lineProperty.get()) {
+			case StraightSolid:
+				updatePolyline((Path)ghost, 0, 0);
+				break;
+			case Bezier:
+				updateBezier((Path)ghost, 0, 0);
+				break;	
+			case BezierSolid:
+				updateBezier((Path)ghost, 0, 0);
+				break;	
+			case Straight:
+				updatePolyline((Path)ghost, 0, 0);				
+				break;
+			case Area:
+				updatePolyline((Path)ghost, 0, 0);
+				break;
+			case TopBottom:
+				updateTopBottom((Path)ghost, 0, 0);
+				break;
+			default:
+				((Path)ghost).getElements().clear();
+				break;
+		}		
+	}
+	
+	@Override
+	protected void refreshShape() {
+		if(updateConnections()) return;
+		
+		if(lineProperty == null || primitif == null) return;
+		
+		switch(lineProperty.get()) {
+			case StraightSolid:
+				paint.bind(strokePaint);
+				updateSolidLine((Path)primitif, 0, 0);
+				break;
+			case Bezier:
+				paint.unbind();
+				paint.set(null);
+				updateBezier((Path)primitif, 0, 0);
+				break;
+			case BezierSolid:
+				paint.bind(strokePaint);
+				updateSolidBezier((Path)primitif, 0, 0);
+				break;
+			case Straight:
+				paint.unbind();
+				paint.set(null);
+				updatePolyline((Path)primitif, 0, 0);
+				break;
+			case TopBottom:
+				paint.unbind();
+				paint.set(null);
+				updateTopBottom((Path)primitif, 0, 0);
+				break;
+			case Area:
+				paint.bind(strokePaint);
+				updateArea((Path)primitif, 0, 0);
+				break;
+			default:
+				paint.unbind();
+				paint.set(null);
+				((Path)primitif).getElements().clear();
+				break;
+		}
+	}
+	
+	
+	@Override
+	public SimpleMark createCopy(Container container, double dx, double dy) { 
+		double x = coords.getX() + (curveSelected ? 0 : dx);
+		double y = coords.getY() + (curveSelected ? 0 : dy);
+		
+		LineConnectedCollection vgroup = new LineConnectedCollection(container, container.addToEnd(x, y));
+		vgroup.setLevel(this.level);
+			
+		List<Mark> marks = new ArrayList<>();		
+		for(Mark mark: components) {
+			if(mark instanceof SimpleMark) {
+				SimpleMark simpleMark = (SimpleMark)mark;
+				SimpleMark copy = curveSelected ? simpleMark.createCopy(vgroup, dx, dy) : simpleMark.createCopy(vgroup, 0, 0);
+				copy.initProperties();
+				marks.add(copy);
+			}
+		}
+		
+		ReferenceCoords refCoords = new ReferenceCoords(RefX.Left, RefY.Bottom);
+		vgroup.setRefCoords(refCoords);
+		
+		for(Mark mark: marks) {
+			vgroup.attachCopy(mark/*, childPropertyStructure.isXShared(), childPropertyStructure.isYShared()*/);
+		}
+		
+		vgroup.setPropertyStructure(PropertyStructure.create(marks, childPropertyStructure));
+		
+		vgroup.toUpdate(false); // Protect the parent tree from property updates
+		vgroup.stealProperties(this);
+		vgroup.coords.x.set(x);
+		vgroup.coords.y.set(y);
+		vgroup.coords.xRef.set(RefX.Left);
+		vgroup.coords.yRef.set(RefY.Bottom);
+		vgroup.toUpdate(true);
+		
+		copyConnectionsTo(vgroup);
+		
+		return vgroup;
+	}
+
+	
+	public void setFlowConnections(FlowConnections connections) {
+		this.flowConnections = connections;
+		
+		for(FlowConnection conn: connections) {
+			addLabel(conn);				
+			conn.getOrigin().addOutwardConnection(conn);
+			conn.getDestination().addInwardConnection(conn);
+		}
+		
+		updateConnections();
+	}
+	
+	// TODO: Problem when including groups!!!!
+	private void copyConnectionsTo(LineConnectedCollection vgroup) {
+		if(flowConnections == null) return;
+		
+		vgroup.coloringScheme.set(coloringScheme.get());
+		vgroup.flowPaint.set(flowPaint.get());
+		
+		vgroup.flowConnections = new FlowConnections(vgroup);
+		for(FlowConnection connection: flowConnections) {
+			ShapeMark source = connection.getOrigin();
+			ShapeMark destination = connection.getDestination();
+			
+			HierarchyPos posSource = new HierarchyPos(source);
+			HierarchyPos posDest = new HierarchyPos(destination);
+			
+			source = (ShapeMark) vgroup.getMarkAt(posSource);
+			destination = (ShapeMark) vgroup.getMarkAt(posDest);
+			
+			vgroup.createConnection(source, destination, false).weight.set(connection.weight.get());
+		}
+		
+		vgroup.updateConnections();
+	}
+	
+	@Override
+	protected Shape primitifCopy(double dx, double dy, boolean shadow) {
+		Path shape = new Path();
+
+		switch(lineProperty.get()) {
+			case StraightSolid:
+				if(shadow) updateBezier(shape, dx, dy);
+				else updateSolidLine(shape, dx, dy);
+				break;
+			case Bezier:
+				updateBezier(shape, dx, dy);
+				break;
+			case BezierSolid:
+				if(shadow) updateBezier(shape, dx, dy); 
+				else updateSolidBezier(shape, dx, dy);
+				break;
+			case Straight:
+				if(shadow) updateBezier(shape, dx, dy);
+				else updatePolyline(shape, dx, dy);
+				break;
+			case TopBottom:
+				updateTopBottom(shape, dx, dy);
+				break;
+			case Area:
+				if(shadow) updateBezier(shape, dx, dy);
+				else updateArea(shape, dx, dy);
+				break;
+		}
+		
+		return shape;
+	}
+	
+	
+	private void changeShape(LineTypeProperty.Type newType) {
+		lineProperty.set(newType);
+		primitif = createShape();
+		shape.replaceBy(primitif);
+		update();
+	}
+	
+	@Override
+	public void stealProperties(SimpleMark mark) {
+		super.stealProperties(mark);
+
+		if(mark instanceof LineConnectedCollection) {
+			LineConnectedCollection vgroup = (LineConnectedCollection)mark;
+			lineProperty = new LineTypeProperty(this, vgroup.lineProperty.get());
+		}
+	}
+	
+		
+	private void updatePolyline(Path path, double dx, double dy) {
+		path.getElements().clear();
+		
+		List<Double> points = new ArrayList<>();
+		
+		for(Mark component: components) {
+			points.add(component.coords.getX() + dx);
+			points.add(-component.coords.getY() + dy);
+		}
+		
+		MoveTo moveTo = new MoveTo();
+		moveTo.setX(points.get(0) + dx);
+		moveTo.setY(points.get(1) + dy);
+		path.getElements().add(moveTo);
+		
+		for(int i = 2; i < points.size(); i+=2) {
+			LineTo lineTo = new LineTo();
+			lineTo.setX(points.get(i) + dx);
+			lineTo.setY(points.get(i+1) + dy);
+			path.getElements().add(lineTo);
+		}
+	}
+	
+	private void updateTopBottom(Path path, double dx, double dy) {
+		path.getElements().clear();
+		List<Double> points1 = new ArrayList<>();
+		List<Double> points2 = new ArrayList<>();
+		
+		if(components.size() > 2) {
+			for(int i = 1 ; i < components.size(); ++i) {
+				points1.add(components.get(i - 1).left() + dx);
+				points1.add(-components.get(i - 1).top() + dy);
+				
+				points2.add(components.get(i).right() + dx);
+				points2.add(-components.get(i).bottom() + dy);
+			}
+		}
+		
+		for(int i = 0; i < points1.size(); i+=2) {
+			MoveTo moveTo = new MoveTo();
+			moveTo.setX(points1.get(i) + dx);
+			moveTo.setY(points1.get(i + 1) + dy);
+			path.getElements().add(moveTo);
+			
+			LineTo lineTo = new LineTo();
+			lineTo.setX(points2.get(i) + dx);
+			lineTo.setY(points2.get(i+1) + dy);
+			path.getElements().add(lineTo);
+		}
+	}
+	
+	private void updateBezier(Path path, double dx, double dy) {
+		path.getElements().clear();
+		
+		List<Point2D> points = new ArrayList<>();
+		for(Mark component: components) {
+			points.add(new Point2D(component.coords.getX() + dx, -component.coords.getY() + dy));
+		}
+		
+		CubicSpline spline = new CubicSpline(path);
+		spline.setPoints(points);
+	}
+	
+	private void updateSolidBezier(Path path, double dx, double dy) { // TODO:...
+		path.getElements().clear();
+		
+		List<Point2D> points = new ArrayList<>();
+		for(Mark component: components) {
+			points.add(new Point2D(component.coords.getX() + dx, dy - component.top()));
+		}
+		for(int i = components.size() - 1; i >= 0; --i) {
+			Mark component = components.get(i);
+			points.add(new Point2D(component.coords.getX() + dx, dy - component.bottom()));
+		}
+
+		//Mark component = components.get(0);
+		//points.add(new Point2D(component.coords.getX() + dx, -component.coords.getY() + dy + component.height()/2));
+		
+		CubicSpline spline = new CubicSpline(path);
+		spline.setPoints(points);
+		
+		path.getElements().add(new ClosePath());
+	}
+	
+	private void updateSolidLine(Path path, double dx, double dy) {
+		path.getElements().clear();
+		
+		double[] points = new double[components.size()*4];
+		int index = 0;
+		for(int i = 0; i < components.size(); i++) {
+			points[index++] = components.get(i).coords.getX();
+			points[index++] = -components.get(i).top();//-components.get(i).coords.getY() + components.get(i).height()/2;
+		}
+		for(int i = components.size() - 1; i >= 0; i--) {
+			points[index++] = components.get(i).coords.getX();
+			points[index++] = -components.get(i).bottom();//-components.get(i).coords.getY() - components.get(i).height()/2;
+		}
+		
+		MoveTo moveTo = new MoveTo();
+		moveTo.setX(points[0] + dx);
+		moveTo.setY(points[1] + dy);
+		path.getElements().add(moveTo);
+		
+		for(int i = 2; i < points.length; i+=2) {
+			LineTo lineTo = new LineTo();
+			lineTo.setX(points[i] + dx);
+			lineTo.setY(points[i+1] + dy);
+			path.getElements().add(lineTo);
+		}
+		
+		path.getElements().add(new ClosePath());
+	}
+	
+	
+	private void updateArea(Path path, double dx, double dy) {
+		path.getElements().clear();
+		
+		List<Double> points = new ArrayList<>();
+		
+		for(Mark component: components) {
+			points.add(component.coords.getX() + dx);
+			points.add(-component.coords.getY() + dy);
+		}
+		points.add(components.get(components.size() - 1).coords.getX() + dx);
+		points.add((double) 0);
+		
+		points.add(components.get(0).coords.getX() + dx);
+		points.add((double) 0);
+		
+		MoveTo moveTo = new MoveTo();
+		moveTo.setX(points.get(0) + dx);
+		moveTo.setY(points.get(1) + dy);
+		path.getElements().add(moveTo);
+		
+		for(int i = 2; i < points.size(); i+=2) {
+			LineTo lineTo = new LineTo();
+			lineTo.setX(points.get(i) + dx);
+			lineTo.setY(points.get(i+1) + dy);
+			path.getElements().add(lineTo);
+		}
+		
+		path.getElements().add(new ClosePath());
+	}
+	
+	@Override
+	public Shadow getShadow(double dx, double dy, double delta) {
+		if(curveSelected) {
+			double d = dy*delta;
+			return new Shadow(this, 0, d, primitifCopy(0, d, true));
+		}
+		else return super.getShadow(dx, dy, delta);
+	}
+
+
+	/*
+	 * This is to create arbitrary connection between the nodes of a top collection
+	 */
+	public FlowConnection createConnection(ShapeMark origin, ShapeMark destination, boolean clever) {
+		if(flowConnections == null) {
+			childPropertyStructure.removeHeightSharing(origin);
+			
+			lineProperty.set(Type.None);
+			lineProperty.getActiveProperty().set(false);
+			
+			strokePaint = null;
+			paint = null;
+			flowConnections = new FlowConnections(this);
+		}
+		
+		FlowConnection connection = flowConnections.addConnection(origin, destination, clever);
+		addLabel(connection);
+		
+		if(connection != null) {
+			updateConnections();
+			origin.addOutwardConnection(connection);
+			destination.addInwardConnection(connection);
+		}
+
+		origin.updateLabels();
+		
+		return connection;
+	}
+	
+	
+	public void removeConnection(FlowConnection flowConnection) {
+		flowConnections.remove(flowConnection);
+		Shape path = connectionShapes.get(flowConnection);
+		shape.remove(path);
+		connectionShapes.remove(flowConnection);
+		
+		removeLabel(flowConnection);
+	}
+	
+	public FlowConnections getFlowConnections() {
+		return flowConnections;
+	}
+	
+	@Override
+	public boolean hasConnections() {
+		return flowConnections != null && !flowConnections.isEmpty();
+	}
+
+			
+	public boolean containtsConnection(ShapeMark origin, ShapeMark destination) {
+		return(flowConnections != null && flowConnections.contains(new FlowConnection(this, origin, destination)));
+	}
+	
+	
+	public boolean hasCycle(ShapeMark from, ShapeMark to) { 
+		if(flowConnections == null) return false;
+		else if(from == to) return true;
+		
+		Set<FlowConnection> connections = flowConnections.from(from);
+		if(connections.isEmpty()) return false;
+		
+		for(FlowConnection conn: connections) {
+			if(hasCycle(conn.getDestination(), to)) return true;
+		}
+		
+		return false;
+	}
+
+	
+	@Override
+	public void translate(Line lineTrace) {
+		if(connectionSelected == null) {
+			super.translate(lineTrace);
+			updateExtraComponents();
+		} else {			
+			double x = pinX + lineTrace.getEndX() - lineTrace.getStartX() - connectionSelected.getOrigin().coords.getX();
+			double y = pinY - lineTrace.getEndY() + lineTrace.getStartY() - connectionSelected.getOrigin().coords.getY();
+			
+					
+			Mark mark = connectionSelected.getDestination();
+			double xdest = x + mark.coords.getX();
+			double ydest = y + mark.coords.getY();
+
+			mark = connectionSelected.getOrigin();
+			mark.coords.x.updateValue(x + mark.coords.getX());
+			mark.coords.y.updateValue(y + mark.coords.getY());
+
+			mark = connectionSelected.getDestination();
+			mark.coords.x.updateValue(xdest);
+			mark.coords.y.updateValue(ydest);					
+									
+			updateInteractor();
+			updateExtraComponents();
+		}
+	}
+	
+	
+	@Override
+	public void setHighlight(boolean highlight, boolean enableControllers) {	
+		if(connectionSelected == null) super.setHighlight(highlight, enableControllers);
+		else { 
+			if(!highlight) {   
+				connectionSelected = null;
+				updateFlowColoring();
+			}
+		}
+	}
+	
+	public boolean isConnectionSelected() {
+		return connectionSelected != null;
+	}
+	
+	public void fullDelete() {
+		if(connectionSelected != null) {
+			removeConnection(connectionSelected);
+			connectionSelected.detachFront();
+			connectionSelected.detachBack();
+			
+			connectionSelected = null;
+			
+			updateConnections();
+		}
+		else {
+			setHighlight(false, true);
+			super.fullDelete();
+		}
+		
+	}
+	
+	@Override
+	public void pin() { 
+		if(connectionSelected == null) super.pin();
+	}
+	
+	public void selectConnection(FlowConnection connection) {
+		if(connection != null) {
+			pinX = connection.getOrigin().coords.getX();
+			pinY = connection.getOrigin().coords.getY();
+		}
+		connectionSelected = connection;
+		updateFlowColoring();
+	}
+	
+	@Override
+	public boolean monoselect(MarkSelection selectedMarks, Circle trace) { 
+		// Handling line connections
+		if(lineProperty != null && lineProperty.get() != LineTypeProperty.Type.None) {
+			curveSelected = false;
+
+			boolean consumed = super.monoselect(selectedMarks, trace);
+			if(consumed) {
+				return consumed;
+			}
+			
+			if(shape.intersects(trace) && components.size() > 0) { 
+				pinX = components.get(0).coords.getX();
+				pinY = components.get(0).coords.getY();
+					
+				selectedMarks.add(this);
+		
+				curveSelected = true;
+						
+				return true;
+			}
+
+			return false;
+		} 
+		else if(flowConnections == null || trace == null) {
+			return super.monoselect(selectedMarks, trace);
+		}
+		else { 
+			// Handling Flow connections
+			boolean consumed = super.monoselect(selectedMarks, trace);	
+			
+			if(consumed) {
+				if(connectionSelected != null) { 
+					connectionSelected = null;
+					updateFlowColoring();
+				}
+				return consumed;
+			}
+			
+			for(FlowConnection connection:flowConnections) {
+				Shape path = connectionShapes.get(connection);
+				Shape intersection = Shape.intersect(path, trace);
+				if(!(intersection instanceof Path) || !((Path)intersection).getElements().isEmpty()) {
+					selectedMarks.add(this);
+
+					pinX = connection.getOrigin().coords.getX();
+					pinY = connection.getOrigin().coords.getY();
+					connectionSelected = connection;
+					
+					updateFlowColoring();
+					return true;
+				}				
+			}
+			
+			connectionSelected = null;
+			updateFlowColoring();
+						
+			return super.monoselect(selectedMarks, trace);
+		}
+	}
+
+	@Override
+	public boolean controlselect(MarkSelection selectedMarks, Circle trace) {	
+		if(flowConnections != null) {
+			connectionSelected = null;
+			updateFlowColoring();			
+		}
+
+		return super.controlselect(selectedMarks, trace);
+	}
+
+
+	@Override
+	public Property getProperty(PropertyName name) {
+		if(name.isCurve()) return lineProperty;
+		else if(name.isOpacity()) return flowOpacity;
+		else if(name.isColoring()) return coloringScheme;
+		else if(name.isFill()) return flowPaint;
+		else return super.getProperty(name);		
+	}
+}
diff --git a/src/fr/inria/structgraphics/graphics/Mark.java b/src/fr/inria/structgraphics/graphics/Mark.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a705b86e2f3aa48580a245708f372652a85bfee
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/Mark.java
@@ -0,0 +1,832 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.List;
+import java.util.Map;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.graphics.controls.Control;
+import fr.inria.structgraphics.types.FillColorProperty;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.HeightProperty;
+import fr.inria.structgraphics.types.OrderProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.RatioLockProperty;
+import fr.inria.structgraphics.types.RatioProperty;
+import fr.inria.structgraphics.types.RotationProperty;
+import fr.inria.structgraphics.types.StrokeColorProperty;
+import fr.inria.structgraphics.types.StrokeWidthProperty;
+import fr.inria.structgraphics.types.WidthProperty;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import fr.inria.structgraphics.ui.tools.MarkSelection;
+import fr.inria.structgraphics.ui.tools.SelectFilter;
+import fr.inria.structgraphics.ui.utils.BidirectionalBindings;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.ConstraintController;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.LabelCollection;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.ConstraintController.ConstraintHandle;
+import javafx.beans.property.Property;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.geometry.Point2D;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Shape;
+import javafx.scene.transform.Rotate;
+import javafx.scene.transform.Translate;
+import javafx.util.Pair;
+
+public abstract class Mark extends Container {
+
+	public WidthProperty width;
+	public HeightProperty height;
+	
+	public RatioProperty hwratio;
+	public RatioLockProperty ratiolock;
+	
+	protected boolean highlighted = false;
+	
+	protected double pinX, pinY; 
+	
+	public PositionCoords coords;
+	protected Container container;
+
+	protected ComplexShape shape = new ComplexShape();
+
+	protected Group controls = new Group();
+	protected Control selectedControl = null;
+	
+	protected LabelCollection labels;
+	
+	// Distribution constraints
+	protected ConstraintController constraintController = null;
+	protected ConstraintController.ConstraintHandle constraintHandler = null;
+	
+	protected int level = 0;
+	
+	public StrokeWidthProperty border = new StrokeWidthProperty(this, 0);
+	public FillColorProperty paint = new FillColorProperty(this);
+	public StrokeColorProperty strokePaint = new StrokeColorProperty (this);
+	public RotationProperty angle = new RotationProperty(this);
+	
+	//protected DoubleProperty distance = new SimpleDoubleProperty(), gap = new SimpleDoubleProperty();
+	
+	public Mark(Container container, boolean toend, double w, double h){
+		super();
+		
+		if(container != null) {
+			container.addMark(this, toend);
+			container.refreshID();
+		}
+		
+		group.getChildren().add(shape);
+		group.getChildren().add(controls);
+		controls.setVisible(false);
+		
+		labels = new LabelCollection(this);
+		group.getChildren().add(labels);
+		
+		this.width = new WidthProperty(this, w);
+		this.height = new HeightProperty(this, h);
+		this.hwratio = new RatioProperty(this, "h-w ratio", w == 0 ? 1 : h/w);
+		this.ratiolock = new RatioLockProperty(this, "lock", false);
+		
+		/*
+		 * Support ratio dependencies between height and width
+		 */
+		ChangeListener<Number> widthListener = new ChangeListener<Number>() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				hwratio.set(height.doubleValue()/newValue.doubleValue());
+			}
+		};
+		ChangeListener<Number> heightListener = new ChangeListener<Number>() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				hwratio.set(newValue.doubleValue()/width.doubleValue());
+			}
+		};
+		width.addListener(widthListener);
+		height.addListener(heightListener);
+		
+		ratiolock.addListener(new ChangeListener<Boolean>() {
+			private Pair<ChangeListener<Number>, ChangeListener<Number>> listeners = null;
+			
+			@Override
+			public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+				if(newValue) {
+					width.removeListener(widthListener);
+					height.removeListener(heightListener);
+					
+					listeners = BidirectionalBindings.bindBidirectional(width, height, 
+						new ChangeListener<Number>() {
+							@Override
+							public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+								height.set(newValue.doubleValue()*hwratio.get());
+							}
+						}, 
+						new ChangeListener<Number>() {
+							@Override
+							public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+								width.set(newValue.doubleValue()/hwratio.get());
+							}
+						}
+					);
+				} else {
+					// TODO: remove binding and add the following
+					BidirectionalBindings.unbindBidirectional(width, height, listeners);
+					
+					width.addListener(widthListener);
+					height.addListener(heightListener);
+				}
+			}
+		});
+				
+	}
+	
+	public void addSelfProperties(boolean toCollection, Map<PropertyName, FlexibleListProperty> table) { // TODO: Name IDS are fucked up !!!!		
+		for(Property property: properties) {
+			FlexibleListProperty list = table.get(new PropertyName(PropertyName.getCleanName(property.getName())));
+			if(list == null) {
+				list = FlexibleListProperty.createList(this, property);
+				table.put(new PropertyName(list.getName()), list);
+			}
+			else {
+				if(isFirst()) list.add(0, property);
+				else list.add(property);
+			}
+		}
+	}
+	
+	
+	public boolean removeSelfProperties(Map<PropertyName, FlexibleListProperty> table) { 
+		boolean removed = false;
+		for(Property property: properties) {
+			FlexibleListProperty list  = table.get(new PropertyName(property.getName()));
+			
+			if(list != null) {
+				if(list.removeProperty(property)) { 
+					removed = true;
+				}
+			}
+		}
+		
+		return removed;
+	}
+	
+	
+	public Mark(Container container){
+		this(container, true, 0, 0);
+	}
+	
+	public boolean isFirst() {
+		return container.components.indexOf(this) == 0;
+	}
+	
+	@Override
+	public void addLeafIDs(List<Property> ids){
+		if(components.isEmpty()) ids.add(id);
+		else super.addLeafIDs(ids);
+	}
+	
+	
+	@Override
+	public void addIDs(List<Property> ids, int level) {
+		if(components.isEmpty()) {
+			if(this.level == level) ids.add(id);
+			else if(container instanceof VisCollection) ((VisCollection)container).addID(ids, level);
+		}
+		else super.addIDs(ids, level);
+	}
+	
+	public int getBottomLevel() {
+		if(components.isEmpty()) return level;
+		Mark component = components.get(0);
+		return component.getBottomLevel();
+	}
+	
+	@Override
+	public void initProperties() {
+		super.initProperties();
+		
+		if(coords != null) {			
+			addProperty(coords.getXRefProperty());
+			addProperty(coords.getYRefProperty());			
+			
+			Mark mark = this;
+			
+			coords.xRef.addListener(new ChangeListener<RefX>() {
+				@Override
+				public void changed(ObservableValue<? extends RefX> observable, RefX oldValue, RefX newValue) {
+					if(container instanceof VisBody) {
+						((VisBody) container).invalidateConstraints(mark);
+						((VisBody)container).updateInteractor();
+						return;
+					}
+						
+					double dx = 0;
+					
+					switch(oldValue) {
+						case Center:
+							if(newValue == RefX.Left) dx = -width.get()/2;
+							else if(newValue == RefX.Right) dx = width.get()/2;
+							break;	
+						case Left:
+							if(newValue == RefX.Center) dx = width.get()/2;
+							else if(newValue == RefX.Right) dx = width.get();
+							break;
+						case Right:
+							if(newValue == RefX.Center) dx = -width.get()/2;
+							else if(newValue == RefX.Left) dx = -width.get();
+							break;
+						default: break;
+					}
+					
+					coords.x.set(coords.getX() + dx);
+					container.updateAll();
+				}
+			});
+			coords.yRef.addListener(new ChangeListener<RefY>() {
+				@Override
+				public void changed(ObservableValue<? extends RefY> observable, RefY oldValue, RefY newValue) {
+					if(container instanceof VisBody) {
+						((VisBody) container).invalidateConstraints(mark);
+						((VisBody)container).updateInteractor();
+						return;
+					}
+					
+					double dy = 0;
+					
+					switch(oldValue) {
+						case Center:
+							if(newValue == RefY.Bottom) dy = -height.get()/2;
+							else if(newValue == RefY.Top) dy = height.get()/2;
+							break;	
+						case Bottom:
+							if(newValue == RefY.Center) dy = height.get()/2;
+							else if(newValue == RefY.Top) dy = height.get();
+							break;
+						case Top:
+							if(newValue == RefY.Center) dy = -height.get()/2;
+							else if(newValue == RefY.Bottom) dy = -height.get();
+							break;
+						default: break;
+					}
+					
+					coords.y.set(coords.getY() + dy);
+					container.updateAll();	
+				}
+			});
+			
+			//addProperty(new DummyProperty(this));
+			
+			addProperty(coords.getXProperty());
+			addProperty(coords.getYProperty());
+		}
+		
+		/*
+		coords.x.addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				List<Mark> siblings = container.getComponents();
+				
+				if(container instanceof VisCollection && ((VisCollection) container).constraintXProperty.get() == Constraint.None) {
+					((VisCollection)container).reorderChildren(true);
+				}
+			}
+		});*/
+	}
+	
+	protected String createID() {
+		int pos = container.getComponents().indexOf(this) + 1;
+		if(container instanceof Mark) return ((Mark) container).createID() + "." + pos;
+		else return "" + pos;
+	}
+	
+	@Override
+	public void refreshID() {
+		id.set(createID());
+		
+		for(Mark mark:components)
+			mark.refreshID();		
+	}
+		
+	public void setLevel(int level) {
+		this.level = level;
+	}
+	
+	public int getLevel() {
+		return level;
+	}
+	
+	protected void initControls() {
+		
+	}
+	
+	public void dispose() {
+		group.getChildren().remove(labels);
+		container.removeMark(this);
+		group.getChildren().remove(shape); // TODO: Is this OK?
+	}
+	
+	public void updateLabels() {
+		labels.update();
+	}
+	
+	public boolean exists() {
+		return container != null;
+	}
+	
+	public void fullDelete() {
+		setHighlight(false, true);
+		
+		dispose();
+		
+		if(container instanceof VisBody) {
+			if(container.getComponents().isEmpty())
+				((VisBody) container).fullDelete();
+		}
+		
+		container = null;
+	}
+	
+	public void setCoords(PositionCoords coords) {
+		this.coords = coords;
+	}
+
+	public void setPositionCoords(double x, double y) {
+		coords.x.updateValue(x);
+		coords.y.updateValue(y);
+	}
+	
+	public void setPositionX(double x) {
+		coords.x.set(x);
+	}
+
+	public void setPositionY(double y) {
+		coords.y.set(y);
+	}
+
+	
+	public PositionCoords getCoords() {
+		return coords;
+	}
+	
+	public void setBorder(int border) {
+		this.border.setValue(border);;
+	}
+	
+	public void setAngle(int angle) {
+		this.angle.set(angle);
+	}
+	
+	public abstract double width();
+	public abstract double height();
+	
+	public double left() {
+		if(coords.getXRef() == RefX.Center) return coords.getX() - width()/2;
+		else if(coords.getXRef() == RefX.Right) return coords.getX() - width();
+		else return coords.getX();
+	}
+		
+	public double right() {
+		if(coords.getXRef() == RefX.Center) return coords.getX() + width()/2;
+		else if(coords.getXRef()  == RefX.Left) return coords.getX() + width();
+		else return coords.getX();
+	}
+	
+	public double centerX() {
+		if(coords.getXRef() == RefX.Center) return coords.getX();
+		else if(coords.getXRef() == RefX.Left) return coords.getX() + width()/2;
+		else return coords.getX() - width()/2;
+	}
+	
+	public double top() {
+		if(coords.getYRef() == RefY.Center) return coords.getY() + height()/2;
+		else if(coords.getYRef()  == RefY.Bottom) return coords.getY() + height();
+		else return coords.getY();
+	}
+	
+	public double bottom() {
+		if(coords.getYRef() == RefY.Center) return coords.getY() - height()/2;
+		else if(coords.getYRef() == RefY.Bottom) return coords.getY();
+		else return coords.getY() - height();
+	}
+	
+	public double centerY() {
+		if(coords.getYRef() == RefY.Center) return coords.getY();
+		else if(coords.getYRef() == RefY.Bottom) return coords.getY()  + height()/2;
+		else return coords.getY() - height()/2;
+	}
+	
+	public void setFill(String fillname) {
+		this.paint.set(Fill.getPaint(fillname));
+	}
+
+	public void setFillColor(String fillname) {
+		if(fillname != null)
+			this.paint.set(Color.web(fillname));
+		else this.paint.set(null);
+	}
+	
+	public void setStrokeColor(String colorname) {
+		this.strokePaint.set(Color.web(colorname));
+	}
+	
+	public Container getContainer(){
+		return container;
+	}
+	
+	public ComplexShape getShape(){
+		return shape;
+	}
+		
+	protected abstract void updateBasicShape();
+	
+	@Override
+	public void clear() {
+		super.clear();
+	//	shape.clear();
+	}
+		
+	protected Point2D getRotationPoint() {
+		double cx = 0, cy = 0;
+		
+		// X axis
+		if(coords.getXRef() == RefX.Left) cx = -width.get()/2;
+		else if(coords.getXRef() == RefX.Right) cx = width.get()/2;
+		else cx = 0;
+		
+		// Y axis
+		if(coords.getYRef() == RefY.Bottom) cy = height.get()/2;
+		else if(coords.getYRef() == RefY.Top) cy = -height.get()/2;
+		else cy = 0;
+		
+		return new Point2D(cx, cy);
+	}
+	
+	public void updateShape(double cx, double cy) {
+		Point2D p = container.getReferencePoint(cx, cy);
+				
+		double xref = p.getX();
+		double yref = p.getY();
+		
+		double refAngle = -container.getRefAngle(cx);
+		if(refAngle != 0) group.getTransforms().add(new Rotate(refAngle, xref, yref));
+		//if(angle.get() != 0) group.getTransforms().add(new Rotate(angle.get(), xref, yref));					
+		
+		//updateBasicShape();
+				
+		group.getTransforms().add(new Translate(xref, yref));
+		updateBasicShape();		
+
+		Point2D r = getRotationPoint();
+		if(angle.get() != 0) group.getTransforms().add(new Rotate(angle.get(), r.getX(), r.getY()));
+
+		if(paint != null) shape.setFill(paint.get());
+		//else shape.setFill(null);
+		
+		if(strokePaint != null) {
+			shape.setStroke(strokePaint.get());
+			shape.setStrokeWidth(border.get());
+		}
+		//else shape.setStroke(Color.DARKGRAY);
+			
+	}
+	
+	
+	@Override
+	public double getRefAngle(double x) {
+		return 0;
+	}
+
+	@Override
+	public String getName() {
+		return "General Mark";
+	}
+
+	@Override
+	public String getType() {
+		return "Graphic";
+	}
+	
+	@Override
+	public void select(MarkSelection selectedMarks, Shape trace, SelectFilter filter) {
+		if(!filter.accept(selectedMarks.getMarks(), this)) return;
+		
+		if(shape.intersects(trace)) {
+			pinX = coords.getX();
+			pinY = coords.getY();
+			selectedMarks.add(this);
+		}
+		
+		super.select(selectedMarks, trace, filter);
+	}
+	
+	
+	public boolean controlselect(MarkSelection selectedMarks, Circle trace) {		
+		selectedControl = null;
+		if(controls.isVisible()) {
+			for(Node node: controls.getChildren()) {
+				if(((Control)node).intersects(trace)) {
+					selectedControl = (Control)node;
+					selectedControl.pin();
+					selectedMarks.add(this);
+					return true;
+				}
+			}
+		}
+		
+		return false;
+	}
+
+	
+	public void pin() {
+		pinX = coords.getX();
+		pinY = coords.getY();
+	}
+	
+	@Override
+	public boolean monoselect(MarkSelection selectedMarks, Circle trace) {		
+		if(super.monoselect(selectedMarks, trace)) return true;
+		
+		if(shape.intersects(trace)) {
+			pin();
+			
+			selectedMarks.add(this);
+			return true;
+		}
+		else return false;
+	}
+		
+	
+	public void setHighlight(boolean highlight, boolean enableControls) { 
+		this.highlighted = highlight;
+		
+		shape.setHighlight(highlight);		
+		if(enableControls) controls.setVisible(highlight);
+		
+		//if(highlight) controls.setVisible(enableControls);
+		//else controls.setVisible(false);
+	}
+
+	public boolean isHighlighted() {
+		return highlighted;
+	}
+	
+	public Mark getHighlightedChild() {
+		return highlighted ? this : null;
+	}
+	
+	public void setConstraintControl(ConstraintController constraintController, ConstraintHandle constraintHandler) {
+		this.constraintController = constraintController;
+		this.constraintHandler = constraintHandler;
+	}
+	
+	
+	public void translate(Line lineTrace) {		
+		if(constraintController != null) {
+			constraintController.translate(lineTrace, constraintHandler);
+		}
+		else if(selectedControl != null) {
+			selectedControl.drag(lineTrace);
+		} else {
+			double dx = lineTrace.getEndX() - lineTrace.getStartX();
+			coords.x.updateValue(pinX + dx);
+			coords.y.updateValue(pinY - lineTrace.getEndY() + lineTrace.getStartY());
+		}
+	}
+	
+	public boolean hasParent(Container node) {
+		if(node == container) return true;
+		else if(container instanceof Mark) return ((Mark)container).hasParent(node);
+		else return false;
+	}
+	
+	public Container getRoot() {
+		if(container instanceof Mark) return ((Mark)container).getRoot();
+		else return container;
+	}
+	
+
+	public double getLeft() {
+		double x = coords.getX();
+		double w = width.get();
+		
+		switch(coords.getXRef()) {
+			case Left: return (w>=0) ? x  : x + w;
+			case Right: return (w>=0) ? x - w : x;
+			default: return (w>=0) ? x - w/2 : x + w/2;
+		}
+	}
+	
+	public double getRight() {
+		double x = coords.getX();
+		double w = width.get();
+		
+		switch(coords.getXRef()) {
+			case Left: return (w>=0) ? x + w  : x;
+			case Right: return (w>=0) ? x : x - w;
+			default: return (w>=0) ? x + w/2 : x - w/2;
+		}
+	}
+	
+	public double getTop() {
+		double y = coords.getY();
+		double h = height.get();
+		
+		switch(coords.getYRef()) {
+			case Bottom: return (h>=0) ? -y - h : -y;
+			case Top: return (h>=0) ? -y : -y + h;
+			default: return (h>=0) ? -y - h/2 : -y + h/2;
+		}
+	}
+	
+	public double getBottom() {
+		double y = coords.getY();
+		double h = height.get();
+		
+		switch(coords.getYRef()) {
+			case Bottom: return (h>=0) ? -y : -y - h;
+			case Top: return (h>=0) ? -y + h : -y;
+			default: return (h>=0) ? -y + h/2 : -y - h/2;
+		}
+	}
+	
+	public double getGlobalX() {
+		return (container instanceof Mark) ?
+			coords.getX() + ((Mark)container).getGlobalX() : coords.getX();
+	}
+	
+	public double getGlobalY() {
+		return (container instanceof Mark) ?
+			coords.getY() + ((Mark)container).getGlobalY() : coords.getY();
+	}
+	
+	public double getGlobalLeft() {
+		return (container instanceof Mark) ?
+			getLeft() + ((Mark)container).getGlobalX() : getLeft();
+	}
+	
+	public double getGlobalBottom() {
+		return (container instanceof Mark) ?
+			getBottom() - ((Mark)container).getGlobalY() : getBottom();
+	}
+	
+	public double getGlobalRight() {
+		return (container instanceof Mark) ?
+			getRight() + ((Mark)container).getGlobalX() : getRight();
+	}
+	
+	public double getGlobalTop() {
+		return (container instanceof Mark) ?
+			getTop() - ((Mark)container).getGlobalY() : getTop();
+	}
+	
+	public double getRootWidth() {
+		return container.getRootWidth();
+	}
+	
+	public double getRootHeight() {
+		return container.getRootHeight();
+	}
+
+
+	public String getNestingPropertyName(String name) {
+		VisGroup topGroup = getTopGroup();
+		if(topGroup == null) return name;
+		else {
+			String id = createID();
+			String pid = topGroup.createID() + ".";
+			
+			return name + id.replaceFirst(pid, "");			
+		}
+	}
+	
+	public VisGroup getTopGroup() {
+		if(container instanceof VisGroup) return ((VisGroup) container).getTopGroup();
+		else return null;
+	}
+	
+	@Override
+	public VisBody getRootVirtualGroup() {
+		if(container instanceof VisBody)
+			return ((VisBody) container).getRootVirtualGroup();
+		else return null;
+	}
+	
+	public VisBody getVirtualGroup() {
+		return container.getVirtualGroup();
+	}
+
+	//public void showLabel(DataVariable variable, Property property) {}
+	
+	//@Override
+	public void showLabel(DataVariable variable, Property property) {
+		if(isLabelShown(variable) == variable.nodeShownProperty.get()) return;
+		labels.showVariable(variable, property);
+	}
+	
+	public boolean isLabelShown(DataVariable variable) {
+		return labels.isLabelShown(variable);
+	}
+	
+	
+	public void mouseRelease() {
+		VisBody vgroup = getVirtualGroup();
+		if(vgroup != null) getVirtualGroup().mouseRelease();
+	}
+
+	public void changeXReference(RefX oldValue, RefX newValue, double w) {
+		if(oldValue == RefX.Left && newValue == RefX.Center || oldValue == RefX.Center && newValue == RefX.Right) {
+			coords.x.set(coords.getX() - w/2);
+		} 
+		else if(oldValue == RefX.Left && newValue == RefX.Right) {
+			coords.x.set(coords.getX() - w);
+		}
+		else if(oldValue == RefX.Center && newValue == RefX.Left || oldValue == RefX.Right && newValue == RefX.Center) {
+			coords.x.set(coords.getX() + w/2);
+		}
+		else if(oldValue == RefX.Right && newValue == RefX.Left) {
+			coords.x.set(coords.getX() + w);
+		}
+	}
+	
+	public void changeYReference(RefY oldValue, RefY newValue, double h) {
+		if(oldValue == RefY.Bottom && newValue == RefY.Center || oldValue == RefY.Center && newValue == RefY.Top) {
+			coords.y.set(coords.getY() - h/2);
+		} 
+		else if(oldValue == RefY.Bottom && newValue == RefY.Center) {
+			coords.y.set(coords.getY() - h);
+		}
+		else if(oldValue == RefY.Center && newValue == RefY.Bottom || oldValue == RefY.Top && newValue == RefY.Center) {
+			coords.y.set(coords.getY() + h/2);
+		}
+		else if(oldValue == RefY.Top && newValue == RefY.Bottom) {
+			coords.y.set(coords.getY() + h);
+		}
+	}
+	
+	/*
+	 * This is a mechanism for updating the coordinates of the marks without undesirable double binding activations
+	*/
+	protected double tentative_x = 0, tentative_y = 0;
+	public void setTentative(double x, double y) {
+		tentative_x = x;
+		tentative_y = y;
+	}
+	
+	public void validateTentative() {
+		if(coords.x.get() != tentative_x) coords.x.set(tentative_x);
+		if(coords.y.get() != tentative_y) coords.y.set(tentative_y);
+	}
+
+	public int getPos() {
+		return container.components.indexOf(this);
+	}
+	
+	public Mark getNodeWithId(String id) {
+		if(id.equals(this.id.get())) return this;
+		
+		for(Mark child : components) {
+			Mark mark = child.getNodeWithId(id);
+			if(mark != null) return mark;
+		}
+		
+		return null;
+	}
+	
+	public Property getProperty(PropertyName name) {
+		if(name.isX()) return coords.x;
+		else if(name.isY()) return coords.y;
+		else if(name.isHeight()) return height;
+		else if(name.isWidth()) return width;
+		else if(name.isFill()) return paint;
+		else if(name.isRotation()) return angle;
+		else if(name.isThickness()) return border;
+		else if(name.isStroke()) return strokePaint;
+		else if(name.isReferenceX()) return coords.xRef;
+		else if(name.isReferenceY()) return coords.yRef;
+		else return null;
+	}
+	
+	public Container getComponent(String sid){
+		if(id.get().equals(sid)) return this;
+		else return super.getComponent(sid);
+	}
+	
+	
+	@Override
+	public double getYIn(Container container) {
+		if(this.container == container) return coords.getY();
+		else return coords.getY() + this.container.getYIn(container);
+	}
+	
+	@Override
+	public double getXIn(Container container) {
+		if(this.container == container) return coords.getX();
+		else return coords.getX() + this.container.getXIn(container);
+	}
+}
diff --git a/src/fr/inria/structgraphics/graphics/MarkFactory.java b/src/fr/inria/structgraphics/graphics/MarkFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1c6b11dcd9d266f174ce8289df378475650de3f
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/MarkFactory.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.graphics;
+
+public class MarkFactory {
+	
+	public static VisFrame createVisFrame(double width, double height) {
+		VisFrame visFrame = new VisFrame(width, height);
+		visFrame.setRefCoords(new ReferenceCoords("left", "bottom"));
+		
+		return visFrame;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/graphics/MultiplyFeedForward.java b/src/fr/inria/structgraphics/graphics/MultiplyFeedForward.java
new file mode 100644
index 0000000000000000000000000000000000000000..11656fa50a932d419f7e705520733cc7c3fc809e
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/MultiplyFeedForward.java
@@ -0,0 +1,95 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javafx.geometry.Point2D;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.shape.Line;
+
+public class MultiplyFeedForward extends Group {
+	
+	private double gapx = 20;
+	private double gapy = 10;
+	private int maxX = 20;
+	private int maxY = 20;
+	
+	private SimpleMark mark;
+	
+	public MultiplyFeedForward(SimpleMark mark) {
+		super();
+		this.mark = mark;
+		
+		if(mark instanceof VisBody) {
+			maxX = 11;
+			maxY = 11;		
+		}
+		
+		build();
+
+	}
+	
+	private void build() {
+		ArrayList<Point2D> positions = MultiplyUtils.getAvailablePositions(mark);
+		if(positions == null) {
+			buildalternative();
+			return;
+		}
+		
+		for(Point2D pos: positions) {
+			getChildren().add(mark.getShadow(pos.getX(), pos.getY(), 1));
+		}
+	}
+	
+	private void buildalternative() {			
+		double W = mark.getRootWidth();
+		double H = mark.getRootHeight();
+		double left = mark.getGlobalLeft();
+		double right = mark.getGlobalRight();
+		double top = -mark.getGlobalTop();
+		double bottom = -mark.getGlobalBottom();
+
+		double dx = Math.abs(mark.width()) + gapx;
+		// TODO: For copying the line????
+		
+		boolean linechart = (mark instanceof LineConnectedCollection) && ((LineConnectedCollection)mark).curveSelected;
+		
+		double dy = linechart  ? 50 : Math.abs(mark.height()) + gapy;
+		
+		if(!linechart) {
+			for(int i = 1; right + dx*i < W && i < maxX; ++ i) {
+				getChildren().add(mark.getShadow(i, 0, dx));
+			}
+			
+			for(int i = 1; left - dx*i > 0 && i < maxX; ++ i) {
+				getChildren().add(mark.getShadow(-i, 0, dx));
+			}
+		}
+				
+		for(int i = 1; top + dy*i < H && i < maxY; ++ i) {
+			getChildren().add(mark.getShadow(0, -i, dy));
+		}
+		
+		for(int i = 1; bottom - dy*i > 0 && i < maxY; ++ i) {
+			getChildren().add(mark.getShadow(0, i, dy));
+		}
+
+	}
+	
+
+	public List<Shadow> select(Line trace) {
+		List<Shadow> selected = new ArrayList<Shadow>();
+		if(trace == null || trace.getStartX() == trace.getEndX() && trace.getStartY() == trace.getEndY()) return selected;
+		
+		for(Node node:getChildren()) {
+			Shadow shadow = (Shadow)node;
+			if(shadow.intersects(trace))
+				selected.add(shadow);
+		}
+		
+		return selected;
+	}
+	
+	
+}
diff --git a/src/fr/inria/structgraphics/graphics/MultiplyUtils.java b/src/fr/inria/structgraphics/graphics/MultiplyUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf21fb12a0db00412a49f3b2fe95186fc6e8579a
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/MultiplyUtils.java
@@ -0,0 +1,115 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.ArrayList;
+
+import fr.inria.structgraphics.types.AlignmentProperty.XSticky;
+import fr.inria.structgraphics.types.AlignmentProperty.YSticky;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import javafx.geometry.Point2D;
+
+public class MultiplyUtils {
+	
+	public static ArrayList<Point2D> getAvailablePositions(Mark mark){
+		VisBody visbody;
+		
+		if(!(mark.getContainer() instanceof VisBody)) {
+			return null;
+		} else visbody = (VisBody) mark.getContainer();
+		
+		double W = visbody.getRootWidth();
+		double H = visbody.getRootHeight();
+		
+		ArrayList<Point2D> positions = new ArrayList<>();
+
+		// TODO: I do not currently consider the case where I have constraints in both x and y directions		
+		if(visbody.constraintXProperty.get() != Constraint.None) {
+			// first do the ones on the right
+			Mark last = visbody.getComponentAt(visbody.components.size() - 1);
+			if(visbody.constraintXProperty.get() == Constraint.Distance) {
+				double xpos = last.getGlobalX() + visbody.distanceXProperty.get(); 
+
+				while(xpos + mark.width() < W) { // TODO: Not correct....
+					positions.add(new Point2D(xpos - mark.getGlobalX(), 0));
+					xpos += visbody.distanceXProperty.get();
+				}
+			} else {
+				double xpos = last.getGlobalX() + Math.abs(last.width()) + visbody.distanceXProperty.get();
+				double dx = Math.abs(mark.width()) + visbody.distanceXProperty.get();
+
+				while(xpos  + mark.width() < W) {
+					positions.add(new Point2D(xpos - mark.getGlobalX(), 0));
+					xpos += dx;
+				}
+			}
+			
+			// And then the ones on the left
+			if(visbody.alignXProperty.get() == YSticky.No) {
+				Mark first = visbody.getComponentAt(0);
+				if(visbody.constraintXProperty.get() == Constraint.Distance) {
+					double xpos = first.getGlobalX() - visbody.distanceXProperty.get(); 
+
+					while(xpos - mark.width() > 0) { // TODO: Not correct....
+						positions.add(new Point2D(xpos - mark.getGlobalX(), 0));
+						xpos -= visbody.distanceXProperty.get();
+					}
+				} else {
+					double xpos = first.getGlobalX() - Math.abs(mark.width()) - visbody.distanceXProperty.get();
+					double dx = -Math.abs(mark.width()) - visbody.distanceXProperty.get();
+
+					while(xpos  - mark.width() > 0) {
+						positions.add(new Point2D(xpos - mark.getGlobalX(), 0));
+						xpos += dx;
+					}
+				}
+			}
+			
+		} else if(visbody.constraintYProperty.get() != Constraint.None) {
+			// first do the ones on the right
+			Mark last = visbody.getComponentAt(visbody.components.size() - 1);
+			if(visbody.constraintYProperty.get() == Constraint.Distance) {				
+				double ypos = last.getGlobalY() + visbody.distanceYProperty.get(); 
+
+				while(ypos + mark.height() < H) { // TODO: Not correct....
+					positions.add(new Point2D(0, -ypos + mark.getGlobalY()));
+					ypos += visbody.distanceYProperty.get();
+				}
+			} else {
+				double ypos = last.getGlobalY() + Math.abs(last.height()) + visbody.distanceYProperty.get();
+				double dy = Math.abs(mark.height()) + visbody.distanceYProperty.get();
+
+				while(ypos  + mark.height() < H) {
+					positions.add(new Point2D(0, -ypos + mark.getGlobalY()));
+					ypos += dy;
+				}
+			}
+			
+			
+			// And then the ones on the BOTTOM
+			if(visbody.alignYProperty.get() == XSticky.No) {
+				Mark first = visbody.getComponentAt(0);
+				if(visbody.constraintYProperty.get() == Constraint.Distance) {
+					double ypos = first.getGlobalY() - visbody.distanceYProperty.get(); 
+
+					while(ypos - mark.height() > 0) { // TODO: Not correct....
+						positions.add(new Point2D(0, -ypos + mark.getGlobalY()));
+						ypos -= visbody.distanceYProperty.get();
+					}
+				} else {
+					double ypos = first.getGlobalY() - Math.abs(mark.height()) - visbody.distanceYProperty.get();
+					double dy = -Math.abs(mark.height()) - visbody.distanceYProperty.get();
+
+					while(ypos  - mark.height() > 0) {
+						positions.add(new Point2D(0, -ypos + mark.getGlobalY()));
+						ypos += dy;
+					}
+				}
+			}
+			
+		} // TODO: To deal with x, y hsaring constrraints.... 
+		else {
+			positions = null;
+		}
+		
+		return positions;
+	}
+}
diff --git a/src/fr/inria/structgraphics/graphics/PositionCoords.java b/src/fr/inria/structgraphics/graphics/PositionCoords.java
new file mode 100644
index 0000000000000000000000000000000000000000..12c06ecfda0973a2ebf834d1acd351ede362e86b
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/PositionCoords.java
@@ -0,0 +1,67 @@
+package fr.inria.structgraphics.graphics;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.ComponentRefXProperty;
+import fr.inria.structgraphics.types.ComponentRefYProperty;
+import fr.inria.structgraphics.types.XProperty;
+import fr.inria.structgraphics.types.YProperty;
+
+public class PositionCoords {
+			
+	public XProperty x;
+	public YProperty  y;
+	
+	public ComponentRefXProperty xRef;
+	public ComponentRefYProperty yRef;
+			
+	public PositionCoords(Mark mark) {
+		this.x = new XProperty(mark);
+		this.y = new YProperty(mark);
+		xRef = new ComponentRefXProperty(mark);
+		yRef = new ComponentRefYProperty(mark);
+	}
+	
+	public PositionCoords(Mark mark, double x, double y) {
+		this.x = new XProperty(mark);
+		this.y = new YProperty(mark);
+		xRef = new ComponentRefXProperty(mark);
+		yRef = new ComponentRefYProperty(mark);
+		
+		this.x.set(x);
+		this.y.set(y);
+	}
+	
+	public double getX() {
+		return x.get();
+	}
+	
+	public double getY() {
+		return y.get();
+	}	
+	
+	public XProperty getXProperty() {
+		return x;
+	}
+	
+	public YProperty getYProperty() {
+		return y;
+	}	
+	
+	public ComponentRefXProperty getXRefProperty() {
+		return xRef;
+	}
+	
+	public ComponentRefYProperty getYRefProperty() {
+		return yRef;
+	}
+	
+	public RefX getXRef() {
+		return xRef.get();
+	}
+	
+	public RefY getYRef() {
+		return yRef.get();
+	}
+}
+
diff --git a/src/fr/inria/structgraphics/graphics/ReferenceCoords.java b/src/fr/inria/structgraphics/graphics/ReferenceCoords.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f524941b7c1b76883eef82279a008a3418018b0
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/ReferenceCoords.java
@@ -0,0 +1,142 @@
+package fr.inria.structgraphics.graphics;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.ContainerRefXProperty;
+import fr.inria.structgraphics.types.ContainerRefYProperty;
+
+public class ReferenceCoords {
+
+	public enum RefX {
+		Left, Right, Center
+	}
+
+	public enum RefY {
+		Center, Top, Bottom
+	}
+	
+	public ContainerRefXProperty containerXRef = new ContainerRefXProperty(this);
+	public ContainerRefYProperty containerYRef = new ContainerRefYProperty(this);
+	
+	/*
+	public ComponentRefXProperty xRef = new ComponentRefXProperty(this);
+	public ComponentRefYProperty yRef = new ComponentRefYProperty(this);
+	*/
+		
+	public ReferenceCoords() {}
+
+	
+	public ReferenceCoords(String contRefx, String contRefy) {
+		setXRef(contRefx);
+		setYRef(contRefy);
+	}
+	
+	/*
+	public ReferenceCoords(String contRefx, String compRefx, String contRefy, String compRefy) {
+		setXRef(contRefx, compRefx);
+		setYRef(contRefy, compRefy);
+	}
+	*/
+			
+	public ReferenceCoords(ReferenceCoords coords) {
+		containerXRef = coords.containerXRef;
+		containerYRef = coords.containerYRef;		
+		
+	//	xRef = coords.xRef;
+	//	yRef = coords.yRef;	
+	}
+
+	public ReferenceCoords(RefX contRefX, RefY contRefY) {
+		containerXRef.set(contRefX);
+		containerYRef.set(contRefY);
+	}
+	
+	/*
+	public ReferenceCoords(RefX contRefX, RefX refX, RefY contRefY, RefY refY) {
+		containerXRef.set(contRefX);
+		xRef.set(refX);
+		containerYRef.set(contRefY);
+		yRef.set(refY);
+	}
+	*/
+	
+	/*
+	public void setXRef(String contRef, String componentRef) {
+		if(contRef.contains("left")) containerXRef.set(RefX.Left);
+		else if(contRef.contains("right")) containerXRef.set(RefX.Right);
+		else containerXRef.set(RefX.Center);	
+		
+		if(componentRef.equals("left")) xRef.set(RefX.Left);
+		else if(componentRef.equals("right")) xRef.set(RefX.Right);
+		else xRef.set(RefX.Center);
+	}
+	
+	public void setYRef(String contRef, String componentRef) {
+		if(contRef.contains("top")) containerYRef.set(RefY.Top);
+		else if(contRef.contains("bottom")) containerYRef.set(RefY.Bottom);
+		else containerYRef.set(RefY.Center);
+		
+		if(componentRef.equals("top")) yRef.set(RefY.Top);
+		else if(componentRef.equals("bottom")) yRef.set(RefY.Bottom);
+		else yRef.set(RefY.Center);
+	}*/
+
+	public static RefX getXRef(String contRef) {
+		if(contRef.equalsIgnoreCase("left")) return RefX.Left;
+		else if(contRef.equalsIgnoreCase("right")) return RefX.Right;
+		else return RefX.Center;	
+	}
+	
+	public static RefY getYRef(String contRef) {
+		if(contRef.equalsIgnoreCase("top")) return RefY.Top;
+		else if(contRef.equalsIgnoreCase("bottom")) return RefY.Bottom;
+		else return RefY.Center;
+	}
+	
+	public void setXRef(String contRef) {
+		if(contRef.contains("left")) containerXRef.set(RefX.Left);
+		else if(contRef.contains("right")) containerXRef.set(RefX.Right);
+		else containerXRef.set(RefX.Center);	
+	}
+	
+	public void setYRef(String contRef) {
+		if(contRef.contains("top")) containerYRef.set(RefY.Top);
+		else if(contRef.contains("bottom")) containerYRef.set(RefY.Bottom);
+		else containerYRef.set(RefY.Center);
+	}
+	
+	public ContainerRefXProperty getContainerXRefProperty() {
+		return containerXRef;
+	}
+	
+	public ContainerRefYProperty getContainerYRefProperty() {
+		return containerYRef;
+	}
+	
+	public RefX getContainerXRef() {
+		return containerXRef.get();
+	}
+	
+	public RefY getContainerYRef() {
+		return containerYRef.get();
+	}
+	
+	/*
+	public ComponentRefXProperty getXRefProperty() {
+		return xRef;
+	}
+	
+	public ComponentRefYProperty getYRefProperty() {
+		return yRef;
+	}
+	
+	public RefX getXRef() {
+		return xRef.get();
+	}
+	
+	public RefY getYRef() {
+		return yRef.get();
+	}
+	*/
+}
+
diff --git a/src/fr/inria/structgraphics/graphics/Shadow.java b/src/fr/inria/structgraphics/graphics/Shadow.java
new file mode 100644
index 0000000000000000000000000000000000000000..535556562fba31730eea34817cf4c1fab6961fb0
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/Shadow.java
@@ -0,0 +1,100 @@
+package fr.inria.structgraphics.graphics;
+
+import javafx.geometry.Point2D;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Shape;
+import javafx.scene.transform.Rotate;
+
+public class Shadow extends Group {
+
+	private double dx, dy;
+	private SimpleMark mark;
+	
+	public Shadow(SimpleMark mark, double dx, double dy) {
+		this.dx = dx;
+		this.dy = dy;
+		this.mark = mark;
+	}
+	
+	public Shadow(SimpleMark mark, double dx, double dy, Shape shape) {
+		this(mark, dx, dy);
+		
+		Point2D r = mark.getRotationPoint();
+		if(mark.angle.get() != 0) shape.getTransforms().add(new Rotate(mark.angle.get(), r.getX() + dx, r.getY() + dy));
+		
+		getChildren().add(shape);
+		
+		highlight(false);
+	}
+	
+	public Shadow(SimpleMark mark, double dx, double dy, Group group) {
+		this(mark, dx, dy);
+		
+		Point2D r = mark.getRotationPoint();
+		if(mark.angle.get() != 0) this.getTransforms().add(new Rotate(mark.angle.get(), r.getX() + dx, r.getY() + dy));
+		
+		getChildren().addAll(group.getChildren());
+		highlight(false);
+	}
+	
+	public void setStroke(Paint paint) {
+		for(Node shape: getChildren()) {
+			if(shape instanceof Shape) ((Shape)shape).setStroke(paint);
+		}
+	}
+
+	public void setStrokeWidth(double border) {
+		for(Node shape: getChildren()) {
+			if(shape instanceof Shape) ((Shape)shape).setStrokeWidth(border);
+		}
+	}
+
+	public void setFill(Paint paint) {
+		for(Node shape: getChildren()) {
+			if(shape instanceof Shape) ((Shape)shape).setFill(paint);
+		}
+	}
+	
+	private void highlight(boolean highlight) {
+		setStrokeWidth(highlight ? 1.8 : 0.7);
+		if(mark instanceof VisCollection) setFill(null);
+		else setFill(new Color(1, 1, 1, 0.5));
+		setStroke(highlight ? Color.CORNFLOWERBLUE : Color.CORNFLOWERBLUE.brighter());
+	}
+	
+	public boolean intersects(Shape trace) {
+		if(trace == null) {
+			highlight(false);
+			return false;
+		}
+		
+		for(Node shape: getChildren()) {
+			if(shape instanceof Shape) {
+				Shape intersection = Shape.intersect((Shape) shape, trace);			
+				if(!(intersection instanceof Path) || !((Path)intersection).getElements().isEmpty()) {
+					highlight(true);
+					return true;
+				}		
+			}
+		}
+		
+		highlight(false);
+		return false;
+	}
+	
+	public double getDeltaX() {
+		return dx;
+	}
+	
+	public double getDeltaY() {
+		return dy;
+	}
+	
+	public SimpleMark createMark() {
+		return mark.createCopy(dx, -dy);
+	}
+}
diff --git a/src/fr/inria/structgraphics/graphics/ShapeMark.java b/src/fr/inria/structgraphics/graphics/ShapeMark.java
new file mode 100644
index 0000000000000000000000000000000000000000..50655c6cf82c4e5ebfae4e29d2cecf61a6b3f35d
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/ShapeMark.java
@@ -0,0 +1,675 @@
+package fr.inria.structgraphics.graphics;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.graphics.controls.Control;
+import fr.inria.structgraphics.graphics.controls.Control.ControlListener;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import fr.inria.structgraphics.ui.tools.MarkSelection;
+import fr.inria.structgraphics.ui.utils.FlowConnectionBinding;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnection;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.LabelCollection;
+import javafx.beans.property.Property;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Shape;
+
+public abstract class ShapeMark extends SimpleMark  {
+	
+	protected Shape primitif;
+	public ShapeProperty shapeProperty; // TODO: turn this to a property...
+	
+	protected Circle flowMarker;
+	
+	public ShapeMark(Container parent, boolean toend, ShapeProperty.Type type, double w, double h){
+		super(parent, toend, w, h);	
+
+		shapeProperty = new ShapeProperty(this, type);
+		primitif = createShape();
+
+		shape.add(primitif);	
+		shape.addToGhost(xghost);
+		shape.addToGhost(yghost);
+		
+	//	labels = new LabelCollection(this);
+	//	group.getChildren().add(labels);
+		
+		initControls();
+	}
+	
+
+	@Override
+	public void stealProperties(SimpleMark mark) {
+		super.stealProperties(mark);
+		if(mark instanceof ShapeMark) {
+			shapeProperty.set(((ShapeMark)mark).shapeProperty.get());	
+			shapeProperty.getPublicProperty().set(((ShapeMark)mark).shapeProperty.getPublicProperty().get());
+		}
+		ratiolock.set(mark.ratiolock.get());
+	}
+		
+	public ShapeProperty getShapeProperty() {
+		return shapeProperty;
+	}
+	
+	public ShapeProperty.Type getShapeType() {
+		return shapeProperty.get();
+	}
+	
+	public static ShapeMark createInstance(Container container, boolean toend, ShapeProperty.Type type, double width, double height) {
+		// New code that has a single class for all types of shapes!!!
+		if(type == ShapeProperty.Type.Text) return new TextualMark(container, toend, width, height);
+		return new GenericShapeMark(container, toend, type, width, height);	
+	}
+	
+	protected abstract Shape createShape();
+	protected abstract void refreshShape();
+				
+	
+	@Override
+	public void dispose() {
+		super.dispose();
+		
+		if(binding != null) {
+			binding.destroy();
+		}
+	}
+	
+	@Override
+	protected void updateBasicShape() {
+		refreshShape();
+		updateControls();
+		updateGhost();
+		labels.update();
+	}
+	
+			
+	@Override
+	public void setHighlight(boolean highlight, boolean enableControls) { 
+		this.highlighted = highlight;
+		shape.setHighlight(highlight);
+		
+		if(enableControls && (width() > 3 || height() > 3)) controls.setVisible(highlight);
+		else  controls.setVisible(false);
+		
+		if(container instanceof VisBody) {
+			VisBody vgroup = (VisBody)container;
+			vgroup.highlighted(this, highlight);			
+		}
+	}
+	
+	
+	@Override
+	public ShapeMark getShape(double x, double y) {
+		if(coords.xRef.get() == RefX.Left) x-= width.get()/2;
+		else if(coords.xRef.get() == RefX.Right) x+= width.get()/2;
+		
+		if(coords.yRef.get() == RefY.Bottom) y-= height.get()/2;
+		else if(coords.yRef.get() == RefY.Top) y+= height.get()/2;
+		
+		if(primitif.contains(x, y)) return this;
+		else return null;
+	}
+	
+	@Override
+	protected void initControls() { // TODO: 
+		startX = new Control();
+		startX.setControlListener(new ControlListener() {
+			private double w, x;
+			
+			@Override
+			public void pin() {
+				x = coords.x.get();
+				w = width.get();
+			}
+			
+			@Override
+			public void offsetX(double offset) {
+				x -= offset;
+			}
+			
+			@Override
+			public void offsetY(double offset) {}
+			
+			@Override
+			public void drag(Line lineTrace) {
+				double delta = lineTrace.getEndX() - lineTrace.getStartX();
+				
+				switch(coords.getXRef()) {
+					case Left:
+						coords.x.set(x + delta);
+						width.updateValue(w - delta);
+						break;
+					case Right:
+						width.updateValue(w - delta);
+						break;
+						
+					default:
+						width.updateValue(w - 2*delta);
+						break;
+				}
+			}
+		});
+		
+		endX = new Control();
+		endX.setControlListener(new ControlListener() {
+			private double w, x;
+			
+			@Override
+			public void pin() {
+				x = coords.x.get();
+				w = width.get();
+			}
+			
+			@Override
+			public void offsetX(double offset) {
+				x -= offset;
+			}
+			
+			@Override
+			public void offsetY(double offset) {}
+			
+			@Override
+			public void drag(Line lineTrace) {
+				double delta = -lineTrace.getEndX() + lineTrace.getStartX();
+				
+				switch(coords.getXRef()) {
+					case Left:
+						width.updateValue(w - delta);
+						break;
+						
+					case Right:
+						coords.x.set(x - delta);
+						width.updateValue(w - delta);
+						break;
+						
+					default:
+						width.updateValue(w - 2*delta);
+						break;
+				}
+			}
+		});
+		
+		endY = new Control();
+		endY.setControlListener(new ControlListener() {
+			private double h, y;
+			
+			@Override
+			public void pin() {
+				y = coords.y.get();
+				h = height.get();
+			}
+			
+			@Override
+			public void offsetX(double offset) {}
+			
+			@Override
+			public void offsetY(double offset) {
+				y+=offset;
+			}
+			
+			@Override
+			public void drag(Line lineTrace) {
+				double delta = lineTrace.getEndY() - lineTrace.getStartY();
+				
+				switch(coords.getYRef()) {
+					case Bottom:
+						height.updateValue(h - delta);
+						break;
+						
+					case Top:
+						coords.y.set(y - delta);
+						height.updateValue(h - delta);
+						break;
+						
+					default:
+						height.updateValue(h - 2*delta);
+						break;
+				}
+			}
+		});
+		
+		startY = new Control();
+		startY.setControlListener(new ControlListener() {
+			private double h, y;
+			
+			@Override
+			public void pin() {
+				y = coords.y.get();
+				h = height.get();
+			}
+			
+			@Override
+			public void offsetX(double offset) {}
+			
+			@Override
+			public void offsetY(double offset) {
+				y+=offset;
+			}
+			
+			@Override
+			public void drag(Line lineTrace) {
+				double delta = -lineTrace.getEndY() + lineTrace.getStartY();
+				
+				switch(coords.getYRef()) {
+					case Bottom:
+						coords.y.set(y + delta);
+						height.updateValue(h - delta);
+						break;
+						
+					case Top:
+						height.updateValue(h - delta);
+						break;
+						
+					default:
+						height.updateValue(h - 2*delta);
+						break;
+				}
+			}
+		});
+		
+		// Code for corner controls
+		//////////////////////////
+		topleft = new Control();
+		topleft.setControlListener(new ControlListener() {
+			private double w, x, y, h;
+			
+			@Override
+			public void pin() {
+				x = coords.x.get();
+				w = width.get();
+				y = coords.y.get();
+				h = height.get();
+			}
+			
+			@Override
+			public void offsetX(double offset) {
+				x -= offset;
+			}
+			
+			@Override
+			public void offsetY(double offset) {
+				y+=offset;
+			}
+			
+			@Override
+			public void drag(Line lineTrace) {
+				double deltax = lineTrace.getEndX() - lineTrace.getStartX();
+				double deltay = -lineTrace.getEndY() + lineTrace.getStartY();
+				
+				switch(coords.getXRef()) {
+					case Left:
+						coords.x.set(x + deltax);
+						width.updateValue(w - deltax);
+						break;
+					case Right:
+						width.updateValue(w - deltax);
+						break;					
+					default:
+						width.updateValue(w - 2*deltax);
+						break;
+				}
+				
+				switch(coords.getYRef()) {
+					case Bottom:
+						coords.y.set(y + deltay);
+						height.updateValue(h - deltay);
+						break;
+						
+					case Top:
+						height.updateValue(h - deltay);
+						break;
+						
+					default:
+						height.updateValue(h - 2*deltay);
+						break;
+				}
+			}
+		});
+		
+		topright = new Control();
+		topright.setControlListener(new ControlListener() {
+			private double w, x, y, h;
+			
+			@Override
+			public void pin() {
+				x = coords.x.get();
+				w = width.get();
+				y = coords.y.get();
+				h = height.get();
+			}
+			
+			@Override
+			public void offsetX(double offset) {
+				x -= offset;
+			}
+			
+			@Override
+			public void offsetY(double offset) {
+				y+=offset;
+			}
+			
+			@Override
+			public void drag(Line lineTrace) {
+				double deltax = -lineTrace.getEndX() + lineTrace.getStartX();
+				double deltay = -lineTrace.getEndY() + lineTrace.getStartY();
+							
+				switch(coords.getXRef()) {
+					case Left:
+						width.updateValue(w - deltax);
+						break;
+						
+					case Right:
+						coords.x.set(x - deltax);
+						width.updateValue(w - deltax);
+						break;
+						
+					default:
+						width.updateValue(w - 2*deltax);
+						break;
+				}
+				
+				switch(coords.getYRef()) {
+					case Bottom:
+						coords.y.set(y + deltay);
+						height.updateValue(h - deltay);
+						break;
+						
+					case Top:
+						height.updateValue(h - deltay);
+						break;
+						
+					default:
+						height.updateValue(h - 2*deltay);
+						break;
+				}
+			}
+		});
+		
+		bottomleft = new Control();
+		bottomleft.setControlListener(new ControlListener() {
+			private double w, x, y, h;
+			
+			@Override
+			public void pin() {
+				x = coords.x.get();
+				w = width.get();
+				y = coords.y.get();
+				h = height.get();
+			}
+			
+			@Override
+			public void offsetX(double offset) {
+				x -= offset;
+			}
+			
+			@Override
+			public void offsetY(double offset) {
+				y+=offset;
+			}
+			
+			@Override
+			public void drag(Line lineTrace) {
+				double deltax = lineTrace.getEndX() - lineTrace.getStartX();
+				double deltay = lineTrace.getEndY() - lineTrace.getStartY();
+				
+				switch(coords.getXRef()) {
+					case Left:
+						coords.x.set(x + deltax);
+						width.updateValue(w - deltax);
+						break;
+					case Right:
+						width.updateValue(w - deltax);
+						break;					
+					default:
+						width.updateValue(w - 2*deltax);
+						break;
+				}
+								
+				switch(coords.getYRef()) {
+					case Bottom:
+						height.updateValue(h - deltay);
+						break;
+						
+					case Top:
+						coords.y.set(y - deltay);
+						height.updateValue(h - deltay);
+						break;
+						
+					default:
+						height.updateValue(h - 2*deltay);
+						break;
+				}
+			}
+		});
+		
+		bottomright = new Control();
+		bottomright.setControlListener(new ControlListener() {
+			private double w, x, y, h;
+			
+			@Override
+			public void pin() {
+				x = coords.x.get();
+				w = width.get();
+				y = coords.y.get();
+				h = height.get();
+			}
+			
+			@Override
+			public void offsetX(double offset) {
+				x -= offset;
+			}
+			
+			@Override
+			public void offsetY(double offset) {
+				y+=offset;
+			}
+			
+			@Override
+			public void drag(Line lineTrace) {
+				double deltax = -lineTrace.getEndX() + lineTrace.getStartX();
+				double deltay = lineTrace.getEndY() - lineTrace.getStartY();
+				
+				switch(coords.getXRef()) {
+					case Left:
+						width.updateValue(w - deltax);
+						break;
+						
+					case Right:
+						coords.x.set(x - deltax);
+						width.updateValue(w - deltax);
+						break;
+						
+					default:
+						width.updateValue(w - 2*deltax);
+						break;
+				}
+								
+				switch(coords.getYRef()) {
+					case Bottom:
+						height.updateValue(h - deltay);
+						break;
+						
+					case Top:
+						coords.y.set(y - deltay);
+						height.updateValue(h - deltay);
+						break;
+						
+					default:
+						height.updateValue(h - 2*deltay);
+						break;
+				}
+			}
+		});
+		
+		//////////////////////////
+		controls.getChildren().addAll(startX, endX, endY, startY, bottomleft, topright, topleft, bottomright);
+	}
+	
+	protected void updateControls() { // TODO: Replace by bindings?
+		startX.moveTo(-width.get()/2, 0);
+		endX.moveTo(width.get()/2, 0);
+		
+		endY.moveTo(0, -height.get()/2);
+		startY.moveTo(0, height.get()/2);
+		
+		topleft.moveTo(-width.get()/2, height.get()/2);
+		topright.moveTo(width.get()/2, height.get()/2);
+		
+		bottomleft.moveTo(-width.get()/2, -height.get()/2);
+		bottomright.moveTo(width.get()/2, -height.get()/2);
+	}
+	
+	@Override
+	public SimpleMark createCopy(Container container, double dx, double dy) { 
+		double x = coords.getX() + dx;
+		double y = coords.getY() + dy;
+		
+		ShapeMark shapeMark = ShapeMark.createInstance(container, container.addToEnd(x, y), shapeProperty.get(), width(), height());
+		
+		shapeMark.stealProperties(this);
+		shapeMark.coords.x.set(x);
+		shapeMark.coords.y.set(y);
+								
+		return shapeMark;
+	}
+
+
+	@Override
+	public boolean monoselect(MarkSelection selectedMarks, Circle trace) {		
+		if(trace == null) return false;
+		if(width() > 3 || height() > 3) return super.monoselect(selectedMarks, trace);		
+		boolean intersects = new Circle(trace.getCenterX(), getRootHeight() - trace.getCenterY(), 10).contains(getGlobalX(), getGlobalY());
+		
+		if(intersects) {
+			pinX = coords.getX();
+			pinY = coords.getY();
+			selectedMarks.add(this);
+		}
+		
+		return intersects;
+	}
+
+
+	public void setDefaults() {
+		border.set(0.5);
+		strokePaint.set(Paint.valueOf("#505080"));
+		coords.xRef.set(RefX.Center);
+	}
+	
+	/*
+	@Override
+	public void showLabel(DataVariable variable, Property property) {
+		if(isLabelShown(variable) == variable.nodeShownProperty.get()) return;
+		labels.showVariable(variable, property);
+	}
+	
+	public boolean isLabelShown(DataVariable variable) {
+		return labels.isLabelShown(variable);
+	}
+	*/
+	
+	/*
+	 * The following is a set of methods for dealing with flow connections (flow diagrams)
+	 * 
+	 */
+	protected FlowConnectionBinding binding;
+	
+	public FlowConnectionBinding getFlowConnectionsBinding() {
+		return binding;
+	}
+	
+	public void addInwardConnection(FlowConnection connection) {
+		if(binding == null) binding = new FlowConnectionBinding(this);
+		binding.addInwardConnection(connection);
+	}
+	
+	public void addOutwardConnection(FlowConnection connection) {
+		if(binding == null) binding = new FlowConnectionBinding(this);
+		binding.addOutwardConnection(connection);
+	}
+	
+	public void removeInwardConnection(FlowConnection connection) {
+		binding.removeInwardConnection(connection);
+	}
+	
+	public void removeOutwardConnection(FlowConnection connection) {
+		binding.removeOutwardConnection(connection);
+	}
+	
+	public boolean hasInwardConnections() {
+		return binding != null && !binding.getInwardConnections().isEmpty();
+	}
+	
+	public boolean hasOutwardConnections() {
+		return binding != null && !binding.getOutwardConnections().isEmpty();
+	}
+	
+	public void lockListeners(boolean lock) {
+		if(binding != null) binding.lockListeners(lock);
+	}
+	
+	////////////////
+	
+	public void showOrigin(boolean show) {
+		if(show && flowMarker == null) {
+			flowMarker = new Circle(5);
+			flowMarker.setStroke(Color.CORNFLOWERBLUE);
+			flowMarker.setFill(null);
+			flowMarker.centerXProperty().set(Math.abs(width.get())/2);
+			flowMarker.centerYProperty().set(0);
+			group.getChildren().add(flowMarker);
+		} else if(!show && flowMarker != null){
+			group.getChildren().remove(flowMarker);
+			flowMarker = null;
+		}
+	}
+	
+	public void showDestination(boolean show) {
+		if(show && flowMarker == null) {
+			flowMarker = new Circle(8);
+			flowMarker.setStroke(Color.CORNFLOWERBLUE);
+			flowMarker.setFill(null);
+			flowMarker.centerXProperty().set(-Math.abs(width.get())/2);
+			flowMarker.centerYProperty().set(0);
+			group.getChildren().add(flowMarker);
+		} else if(!show && flowMarker != null){
+			group.getChildren().remove(flowMarker);
+			flowMarker = null;
+		}
+	}
+	
+	///////////////////
+	private double originYflag = 0, destinationYflag = 0;
+	void increaseOriginFlag(double dy) {
+		originYflag += dy;
+	}
+	
+	void increaseDestinationFlag(double dy) {
+		destinationYflag += dy;
+	}
+	
+	void resetConnectionFlags() {
+		originYflag = 0;
+		destinationYflag = 0;
+	}
+	
+	double getOriginFlag() {
+		return originYflag;
+	}
+	
+	double getDestinationFlag() {
+		return destinationYflag;
+	}
+	
+	@Override
+	public Property getProperty(PropertyName name) {
+		if(name.isShape()) return shapeProperty;
+		else return super.getProperty(name);		
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/graphics/SimpleMark.java b/src/fr/inria/structgraphics/graphics/SimpleMark.java
new file mode 100644
index 0000000000000000000000000000000000000000..b76a25006fdaeed2c47828b4a27091779b4be7e3
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/SimpleMark.java
@@ -0,0 +1,200 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.graphics.controls.Control;
+import fr.inria.structgraphics.types.Shareable;
+import javafx.beans.property.Property;
+import javafx.geometry.Point2D;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Rectangle;
+
+public abstract class SimpleMark extends Mark  {
+	
+	protected Arrow xghost = new Arrow(), yghost = new Arrow();
+	protected MultiplyFeedForward mfeedforward = null;
+	
+	// These are less important properties to be somehow linked to the main properties
+	protected Control startX, endX, startY, endY;
+	
+	// Additional controls for the corners
+	protected Control topleft, topright, bottomleft, bottomright;
+	
+	public SimpleMark(Container parent, boolean toend, double width, double height){
+		super(parent, toend, width, height);		
+	}
+	
+	@Override
+	public void initProperties() {
+		super.initProperties();
+		
+		addProperty(this.width);
+		addProperty(this.height);
+		
+		addProperty(border);
+		addProperty(angle);
+		
+		addProperty(paint);
+		addProperty(strokePaint);
+	}
+		
+	
+	public void stealProperties(SimpleMark mark) {
+		border.set(mark.border.get());
+		border.getPublicProperty().set(mark.border.getPublicProperty().get());
+		
+		if(mark.paint != null) {
+			paint.set(mark.paint.get());
+			paint.getPublicProperty().set(mark.paint.getPublicProperty().get());
+		} else paint = null;
+
+		
+		angle.set(mark.angle.get());
+		angle.getPublicProperty().set(mark.angle.getPublicProperty().get());
+		
+		if(mark.strokePaint != null) {
+			strokePaint.set(mark.strokePaint.get());
+			strokePaint.getPublicProperty().set(mark.strokePaint.getPublicProperty().get());
+		} else mark.strokePaint = null;
+		
+		coords = new PositionCoords(this, mark.coords.getX(), mark.coords.getY());	
+		coords.x.getPublicProperty().set(mark.coords.x.getPublicProperty().get());
+		coords.y.getPublicProperty().set(mark.coords.y.getPublicProperty().get());
+		
+		coords.xRef.set(mark.coords.getXRef());
+		coords.xRef.getPublicProperty().set(mark.coords.xRef.getPublicProperty().get());
+		
+		coords.yRef.set(mark.coords.getYRef());
+		coords.yRef.getPublicProperty().set(mark.coords.yRef.getPublicProperty().get());
+		
+		width.getPublicProperty().set(mark.width.getPublicProperty().get());
+		height.getPublicProperty().set(mark.height.getPublicProperty().get());
+	}
+		
+	public double width() {
+		return width.get();
+	}
+	
+	public double height() {
+		return height.get();
+	}
+	
+	public Arrow getXGhost() {
+		return xghost;
+	}
+	
+	public Arrow getYGhost() {
+		return yghost;
+	}
+	
+	// This is some code for creating and handling the ghost
+	public void updateGhost() {
+		switch(coords.getXRef()) {
+			case Left:
+				xghost.setEnds(-width.get()/2, -width.get()/2, height.get()/2, -height.get()/2);
+				break;
+				
+			case Right:
+				xghost.setEnds(width.get()/2, width.get()/2, height.get()/2, -height.get()/2);
+				break;
+				
+			default:
+				xghost.setEnds(0, 0, height.get()/2, -height.get()/2);
+				break;
+		}
+		
+		switch(coords.getYRef()) {
+			case Top:
+				yghost.setEnds(-width.get()/2, width.get()/2, -height.get()/2, -height.get()/2);
+				break;
+				
+			case Bottom:
+				yghost.setEnds(-width.get()/2, width.get()/2, height.get()/2, height.get()/2);
+				break;
+				
+			default:
+				yghost.setEnds(-width.get()/2, width.get()/2, 0, 0);
+				break;
+		}
+		
+	}
+	
+	@Override
+	public void updateShape() {
+		double cx = 0, cy = 0;
+		
+		// X axis
+		if(coords.getXRef() == RefX.Left) cx = coords.getX() + width.get()/2;
+		else if(coords.getXRef() == RefX.Right) cx = coords.getX() - width.get()/2;
+		else cx = coords.getX();
+		
+		// Y axis
+		if(coords.getYRef() == RefY.Bottom) cy = coords.getY() + height.get()/2;
+		else if(coords.getYRef() == RefY.Top) cy = coords.getY() - height.get()/2;
+		else cy = coords.getY();
+					
+		// TODO: I also need to derive the angle in case the parent is a curve!!! 
+				
+		super.updateShape(cx, cy);
+		
+	}
+	
+	@Override
+	public Point2D getReferencePoint(double cx, double cy) {
+		double x, y;
+	
+		if(refCoords.containerXRef.get() == RefX.Left) x = cx - width.get()/2; 
+		else if(refCoords.containerXRef.get() == RefX.Right) x = width.get()/2 + cx; 
+		else x = cx;
+		
+		if(refCoords.containerYRef.get() == RefY.Top) y = -cy - height.get()/2; 
+		else if(refCoords.containerYRef.get() == RefY.Bottom) y = height.get()/2 - cy; 
+		else y = -cy;
+		
+		return new Point2D(x, y);
+	}
+	
+
+	public void setFeedForward(boolean activate) {
+		VisFrame frame = (VisFrame)getRoot();	
+		
+		if(activate) {
+			mfeedforward = new MultiplyFeedForward(this);
+			
+			Point2D ref = getRotationPoint();
+			mfeedforward.translateXProperty().set(mfeedforward.translateXProperty().get() + getGlobalX() - ref.getX());
+			mfeedforward.translateYProperty().set(mfeedforward.translateYProperty().get() + getRootHeight() - getGlobalY() - ref.getY());
+					
+			getRoot().getGroup().getChildren().add(frame.createBedSheet());
+			getRoot().getGroup().getChildren().add(mfeedforward);
+		}
+		else {
+			getRoot().getGroup().getChildren().remove(mfeedforward);
+			getRoot().getGroup().getChildren().remove(frame.getBedSheet());
+			
+			mfeedforward = null;
+		}
+	}
+	
+	public Shadow getShadow(double dx, double dy, double delta) { 
+		return new Shadow(this, dx*delta, dy*delta); // TODO: ???
+	}
+	
+	
+	public SimpleMark createCopy(double dx, double dy) { // TODO: Turn to abstract?
+		return createCopy(this.container, dx, dy);
+	}
+	
+	public SimpleMark createCopy(Container container, double dx, double dy) {
+		return null;
+	}
+
+	public List<Shadow> selectCopies(Line lineTrace) {
+		return mfeedforward.select(lineTrace);
+	}
+
+
+}
diff --git a/src/fr/inria/structgraphics/graphics/TextualMark.java b/src/fr/inria/structgraphics/graphics/TextualMark.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b1d11da04a0dbd3fdabbf67d6dd10fdb4bad6f1
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/TextualMark.java
@@ -0,0 +1,211 @@
+package fr.inria.structgraphics.graphics;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.FontSizeProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.types.TextProperty;
+import javafx.beans.property.Property;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.EventHandler;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.shape.Shape;
+import javafx.scene.text.Font;
+import javafx.scene.text.Text;
+import javafx.scene.text.TextAlignment;
+
+public class TextualMark extends ShapeMark  {
+	
+	public TextProperty textProperty = new TextProperty(this, "your text");
+	public FontSizeProperty fontSize = new FontSizeProperty(this, 14);
+	
+	protected TextualMark(Container parent, boolean toend, double w, double h){
+		super(parent, toend, ShapeProperty.Type.Text, w, h);	
+	}
+	
+	@Override
+	public void initProperties() {
+		super.initProperties();
+		removeProperty(border);
+		removeProperty(strokePaint);
+		
+		switch(coords.xRef.get()) {
+			case Center: ((Text)primitif).setTextAlignment(TextAlignment.CENTER);
+				break;
+			case Left: ((Text)primitif).setTextAlignment(TextAlignment.LEFT);
+				break;
+			case Right: ((Text)primitif).setTextAlignment(TextAlignment.RIGHT);
+				break;
+			default:
+				break;
+		}	
+		
+		coords.xRef.addListener(new ChangeListener<RefX>() {
+			@Override
+			public void changed(ObservableValue<? extends RefX> observable, RefX oldValue, RefX newValue) {
+				switch(newValue) {
+					case Center: ((Text)primitif).setTextAlignment(TextAlignment.CENTER);
+						break;
+					case Left: ((Text)primitif).setTextAlignment(TextAlignment.LEFT);
+						break;
+					case Right: ((Text)primitif).setTextAlignment(TextAlignment.RIGHT);
+						break;
+					default:
+						break;
+				}
+			}
+		});
+
+		
+		//Text text = new Text(-Math.abs(width.get())/2, Math.abs(height.get())/2, "title");
+		coords.yRef.addListener(new ChangeListener<RefY>() {
+			@Override
+			public void changed(ObservableValue<? extends RefY> observable, RefY oldValue, RefY newValue) {
+				switch(newValue) {
+					case Center: ((Text)primitif).setY(0);
+						break;
+					case Bottom: ((Text)primitif).setY(height.get()/2);
+						break;
+					case Top: ((Text)primitif).setY(-height.get()/2);
+						break;
+					default:
+						break;
+				}
+			}
+		});
+		switch(coords.yRef.get()) {
+			case Center: ((Text)primitif).setY(0);
+				break;
+			case Bottom: ((Text)primitif).setY(height.get()/2);
+				break;
+			case Top: ((Text)primitif).setY(-height.get()/2);
+				break;
+			default:
+				break;
+		}
+		
+		((Text)primitif).setFont(new Font(fontSize.get()));		
+		fontSize.addListener(
+				new ChangeListener<Number>() {
+					@Override
+					public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+						((Text)primitif).setFont(new Font(fontSize.get()));
+					}
+		});
+				
+		((Text)primitif).textProperty().bindBidirectional(textProperty);
+		
+		addProperty(textProperty);
+		addProperty(fontSize);
+	}
+	
+	@Override
+	public void stealProperties(SimpleMark mark) {
+		super.stealProperties(mark);
+		if(mark instanceof TextualMark) {
+			textProperty.set(((TextualMark)mark).textProperty.get());	
+			textProperty.getPublicProperty().set(((TextualMark)mark).textProperty.getPublicProperty().get());
+			
+			fontSize.set(((TextualMark)mark).fontSize.get());	
+			fontSize.getPublicProperty().set(((TextualMark)mark).fontSize.getPublicProperty().get());
+		}
+	}
+	
+	@Override
+	protected Shape createShape() {
+		Text text = new Text(-width.get()/2, height.get()/2, "title");
+
+		text.wrappingWidthProperty().bind(width);
+		//width.set(text.getLayoutBounds().getWidth());
+		
+		text.onMouseClickedProperty().set(new EventHandler<MouseEvent>() {
+			TextField field = null;
+			@Override
+			public void handle(MouseEvent event) {
+				if(event.getClickCount() > 1 && field == null) {
+					field = new TextField(text.getText());
+					field.translateXProperty().set(getGlobalX());
+					field.translateYProperty().set(getRootHeight() - getGlobalY());
+					getRoot().addTextField(field, true);
+					field.setOnKeyPressed(new EventHandler<KeyEvent>() { 	
+			            public void handle(KeyEvent ke) { 
+			                if (ke.getCode().equals(KeyCode.ENTER)) {
+			                	text.setText(field.getText()); 
+			                	getRoot().addTextField(field, false);
+			                	getRoot().update();
+			                	field = null;
+			                } else {
+			                	
+			                }
+			            }
+			        });
+
+					
+				} else if(field != null) {
+                	getRoot().addTextField(field, false);
+                	getRoot().update();
+                	field = null;
+				}
+			}
+		});
+		
+		return text;
+	} 
+
+	@Override
+	protected void refreshShape() {
+		Text text = (Text)primitif;
+		text.xProperty().set(-width.get()/2); 
+
+		switch(coords.yRef.get()) {
+			case Center: ((Text)primitif).setY(0);
+				break;
+			case Bottom: ((Text)primitif).setY( height.get()/2);
+				break;
+			case Top: ((Text)primitif).setY(-height.get()/2);
+				break;
+			default:
+				break;
+		}		
+	}
+	
+			
+	@Override
+	public String getName() {
+		return shapeProperty.get().name();
+	}
+
+	@Override
+	public String getType() {
+		return shapeProperty.get().name();	}
+				
+	
+	@Override
+	public Shadow getShadow(double dx, double dy, double delta) {
+		dx *= delta;
+		dy *= delta;
+		
+		return new Shadow(this, dx, dy, new Rectangle(dx-Math.abs(width.get())/2, dy-Math.abs(height.get())/2, 
+				Math.abs(width.get()), Math.abs(height.get()))); // TODO: ???
+	}
+
+	@Override
+	public void setDefaults() {
+		border.set(0);
+		paint.set(Color.DIMGREY);
+	}
+	
+	@Override
+	public Property getProperty(PropertyName name) {
+		if(name.isFontSize()) return fontSize;
+		else if(name.isText()) return textProperty;
+		else return super.getProperty(name);		
+	}
+}
diff --git a/src/fr/inria/structgraphics/graphics/VisBody.java b/src/fr/inria/structgraphics/graphics/VisBody.java
new file mode 100644
index 0000000000000000000000000000000000000000..83cb9233047dab4cb6294c65ebf12cc934624d2c
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/VisBody.java
@@ -0,0 +1,1079 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.AlignmentXProperty;
+import fr.inria.structgraphics.types.AlignmentYProperty;
+import fr.inria.structgraphics.types.DeltaXProperty;
+import fr.inria.structgraphics.types.DeltaYProperty;
+import fr.inria.structgraphics.types.DistributionProperty;
+import fr.inria.structgraphics.types.DistributionXProperty;
+import fr.inria.structgraphics.types.DistributionYProperty;
+import fr.inria.structgraphics.types.IdentifierProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.XMinProperty;
+import fr.inria.structgraphics.types.YMinProperty;
+import fr.inria.structgraphics.types.AlignmentProperty.XSticky;
+import fr.inria.structgraphics.types.AlignmentProperty.YSticky;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import fr.inria.structgraphics.types.ShapeProperty.Type;
+import fr.inria.structgraphics.ui.tools.MarkSelection;
+import fr.inria.structgraphics.ui.tools.SelectFilter;
+import fr.inria.structgraphics.ui.utils.SortedMarkSet;
+import fr.inria.structgraphics.ui.viscanvas.groupings.DefaultSharingStrategy;
+import fr.inria.structgraphics.ui.viscanvas.groupings.PropertyStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.BodyInteractor;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.ConstraintController;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.ConstraintXController;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.ConstraintYController;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.Property;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.geometry.Point2D;
+import javafx.scene.Group;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Shape;
+
+public abstract class VisBody extends SimpleMark implements InvalidationListener {
+		
+	protected PropertyStructure childPropertyStructure;
+	
+	public AlignmentXProperty alignXProperty = new AlignmentXProperty(this);
+	public AlignmentYProperty alignYProperty = new AlignmentYProperty(this);
+	
+	public DistributionXProperty constraintXProperty = new DistributionXProperty(this);
+	public DistributionYProperty constraintYProperty = new DistributionYProperty(this);
+	
+	public DeltaYProperty distanceYProperty = new DeltaYProperty(this);
+	public DeltaXProperty distanceXProperty = new DeltaXProperty(this);
+
+	// TODO: add them!!!!!
+	public YMinProperty minYProperty = new YMinProperty(this);
+	public XMinProperty minXProperty = new XMinProperty(this);
+	
+	// These are additional properties used for interaction and visualization purposes
+	protected BodyInteractor interactor;
+	protected ConstraintController controllerX, controllerY;
+
+	protected Group shapes  = new Group();
+	
+	protected boolean toUpdateLayout = true;
+	
+	public VisBody(Container parent, boolean toend) {
+		super(parent, toend, 0, 0);
+	
+		group.getChildren().add(shapes);
+		
+		interactor = createInteractor();
+		group.getChildren().add(interactor);
+		
+		addExtraComponents();
+		
+		controllerX  = new ConstraintXController(this);
+		group.getChildren().add(controllerX);
+		
+		controllerY  = new ConstraintYController(this);
+		group.getChildren().add(controllerY);
+				
+		
+		alignXProperty.addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				if(components.isEmpty()) return;
+				
+				if(alignXProperty.get() == YSticky.Yes) {
+						if(constraintXProperty.get() == Constraint.None) {
+							childPropertyStructure.moveToCommon(new PropertyName(components.get(0).coords.x.getName()));
+							
+							for(Mark mark: components) { // TODO: needed all this?
+								mark.coords.x.set(0);
+								mark.coords.x.getActiveProperty().set(false);
+							}
+							//constraintXProperty.setValue(Constraint.None);
+							//constraintXProperty.getActiveProperty().set(false);
+						} else { 
+							// TODO: ????
+							components.get(0).coords.x.set(0);
+							HierarchyPos pos = new HierarchyPos(components.get(0));
+							getRootVirtualGroup().updateTreeLayout(pos);
+							//
+						}
+				} else {
+					for(Mark mark: components) {
+						mark.coords.x.getActiveProperty().set(true);
+					}
+				}
+						
+				invalidateInteractor();
+			}
+		});
+		
+		alignYProperty.addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				if(components.isEmpty()) return;
+				
+				if(alignYProperty.get() == XSticky.Yes) {
+						if(constraintYProperty.get() == Constraint.None) {
+							childPropertyStructure.moveToCommon(new PropertyName(components.get(0).coords.y.getName()));
+							
+							for(Mark mark: components) {
+								mark.coords.y.set(0);
+								mark.coords.y.getActiveProperty().set(false);
+							}
+							// constraintYProperty.setValue(Constraint.None);
+							// constraintYProperty.getActiveProperty().set(false);					
+						} else { // TODO:???
+							components.get(0).coords.y.set(0);
+							HierarchyPos pos = new HierarchyPos(components.get(0));
+							getRootVirtualGroup().updateTreeLayout(pos);
+						}
+				} else {
+					for(Mark mark: components) {
+						mark.coords.y.getActiveProperty().set(true);
+					}
+				}
+				
+				invalidateInteractor();
+			}
+		});	
+	}
+	
+	protected abstract BodyInteractor createInteractor();
+	
+	protected void addExtraComponents() {
+		
+	}
+	
+	protected void updateExtraComponents() {
+		
+	}
+	
+	////////////////////////////////////////////////////////////
+	public boolean isOrderConstrained() {
+		if(constraintXProperty.get() == DistributionProperty.Constraint.None 
+				&& constraintYProperty.get() == DistributionProperty.Constraint.None) return false;
+		else return true;
+	}
+			
+	public DistributionXProperty getConstraintXProperty() {
+		return constraintXProperty;
+	}
+	
+	public DistributionYProperty getConstraintYProperty() {
+		return constraintYProperty;
+	}
+	
+	public AlignmentXProperty getAlignXProperty() {
+		return alignXProperty;
+	}
+	
+	public AlignmentYProperty getAlignYProperty() {
+		return alignYProperty;
+	}
+	
+	
+	public void setLevel(int level) {
+		this.level = level;
+		id = new IdentifierProperty(this, PropertyName.getPrefix(level) + "id");
+	}
+	
+	@Override
+	protected void updateBasicShape() { 
+		labels.update();
+	}
+	
+	public BodyInteractor getInteractor() {
+		return interactor;
+	}
+	
+	@Override
+	public void updateShape() {
+		super.updateShape(coords.getX(), coords.getY());
+		
+	}
+	
+	@Override
+	public Point2D getReferencePoint(double cx, double cy) {
+		return new Point2D(cx, -cy);
+	}
+			
+	@Override
+	public void initProperties() {
+		if(coords != null) {						
+			addProperty(coords.getXProperty());
+			addProperty(coords.getYProperty());
+		}
+			
+		//if(this instanceof VisCollection) {
+		addProperty(alignXProperty);
+		addProperty(alignYProperty);
+		//}
+
+		addProperty(constraintXProperty);
+		addProperty(constraintYProperty);
+							
+		constraintXProperty.addListener(new ChangeListener<Constraint>() {
+			@Override
+			public void changed(ObservableValue observable, Constraint oldValue, Constraint newValue) {
+				// TODO Auto-generated method stub				
+				if(newValue == Constraint.None 
+						|| newValue == Constraint.Distance) { // TODO: CORRECT?
+					distanceXProperty.getActiveProperty().set(false);
+					alignXProperty.set(YSticky.No);
+				}
+				else {						
+					distanceXProperty.getActiveProperty().set(true);
+					if(alignXProperty.get() == YSticky.Yes) {
+						
+						for(Mark mark: components) {
+							mark.coords.x.getActiveProperty().set(true);
+						}
+						childPropertyStructure.moveToVariable(new PropertyName(components.get(0).coords.x.getName()));
+						distanceXProperty.set(10);
+					} else childPropertyStructure.moveToVariable(new PropertyName(components.get(0).coords.x.getName()));
+					
+					if(container instanceof VisBody) {
+						((VisBody) container).childPropertyStructure.fixXSharing();
+					}
+				}				
+			}
+		});
+		
+		constraintYProperty.addListener(new ChangeListener<Constraint>() {
+			@Override
+			public void changed(ObservableValue observable, Constraint oldValue, Constraint newValue) {
+				if(newValue == Constraint.None 
+						|| newValue == Constraint.Distance) { // TODO: Correct?
+					distanceYProperty.getActiveProperty().set(false);
+					alignYProperty.set(XSticky.No);
+				}
+				else {					
+					distanceYProperty.getActiveProperty().set(true);
+					if(alignYProperty.get() == XSticky.Yes) {
+						for(Mark mark: components) {
+							mark.coords.y.getActiveProperty().set(true);
+						}
+						childPropertyStructure.moveToVariable(new PropertyName(components.get(0).coords.y.getName()));
+						distanceYProperty.set(10);
+					} else {
+						childPropertyStructure.moveToVariable(new PropertyName(components.get(0).coords.y.getName()));
+					}
+					
+					
+					if(container instanceof VisBody) {
+						((VisBody) container).childPropertyStructure.fixYSharing();
+					}
+				}
+			}
+		});
+				
+		addProperty(angle);
+		
+		// TODO: To remove them from the UI - make them shared???
+		addProperty(distanceXProperty);
+		addProperty(distanceYProperty);	
+		
+		/*
+		// Update order when necessary!
+		coords.x.addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				List<Mark> siblings = container.getComponents();
+				
+				if(container instanceof VisCollection && ((VisCollection) container).constraintXProperty.get() == Constraint.None) {
+					((VisCollection)container).reorderChildren(true);
+				}
+			}
+		});*/
+	}
+		
+	public void initVisibility() {
+		distanceXProperty.getActiveProperty().set(false);
+		distanceYProperty.getActiveProperty().set(false);
+	}
+	
+	
+	public void updateInteractor() {
+		double left = Double.MAX_VALUE, right = -Double.MAX_VALUE, top = Double.MAX_VALUE, bottom = -Double.MAX_VALUE;
+//		double minX = Double.MAX_VALUE, maxX = -Double.MAX_VALUE, maxY = Double.MAX_VALUE, minY = -Double.MAX_VALUE;
+	
+		for(Mark mark:components) {
+			left = Math.min(left, mark.getLeft());	
+			right = Math.max(right, mark.getRight());
+			top = Math.min(top, mark.getTop());
+			bottom = Math.max(bottom, mark.getBottom());			
+		}
+		
+		YSticky alignX = alignXProperty.get();
+		
+		if(alignX == YSticky.No) {
+			interactor.left.set(Math.min(0, left));
+			interactor.right.set(Math.max(0, right));
+		} else {
+			interactor.left.set(left);
+			interactor.right.set(right);
+		}
+				
+		XSticky alignY = alignYProperty.get();
+		if(alignY == XSticky.No) {
+			interactor.top.set(Math.min(0, top));
+			interactor.bottom.set(Math.max(0, bottom));
+		} else {
+			interactor.top.set(top);
+			interactor.bottom.set(bottom);			
+		}
+
+		interactor.refresh();
+	}
+	
+	/*
+	 * Re-orders all children based on 
+	 */
+	public void reorderChildren(boolean xaxis) { 
+		if(xaxis && (alignXProperty.get() == YSticky.Yes || childPropertyStructure.isXShared() 
+				|| constraintYProperty.get() != Constraint.None)
+				|| !xaxis && (alignYProperty.get() == XSticky.Yes || childPropertyStructure.isYShared()
+				|| constraintXProperty.get() != Constraint.None)) return;
+			
+		boolean ordered = true;
+		
+		if(xaxis) {
+			for(int i = 1; i < components.size() && ordered; ++ i) {
+				if(components.get(i).coords.getX() <  components.get(i - 1).coords.getX())
+					ordered = false;				
+			}
+		} else {
+			// TODO: CHECK
+			for(int i = 1; i < components.size() && ordered; ++ i) {
+				if(components.get(i).coords.getY() <  components.get(i - 1).coords.getY())
+					ordered = false;				
+			}
+		}
+		if(ordered) return;
+		
+		//TODO: This is incomplete. i need to take care of the properties structure and update the inspector?
+		SortedMarkSet sorted = new SortedMarkSet(xaxis);
+		sorted.addAll(components);
+		
+		for(Mark mark: components) {
+			shapes.getChildren().remove(mark.group);
+		}		
+		components.clear();
+				
+		for(Mark mark: sorted) {
+			components.add(mark);
+		}
+		
+		for(Mark mark: sorted) {
+			shapes.getChildren().add(mark.group);
+		}
+	
+		updateReordering(sorted);
+		
+	}
+	
+	protected void updateReordering(Collection<Mark> marks) {
+		refreshID();
+		
+		PropertyStructure structure = PropertyStructure.create(marks, childPropertyStructure);
+		childPropertyStructure.destroyAllBindings();
+		setPropertyStructure(structure);
+		
+		if(container instanceof VisBody) ((VisBody)container).updateReordering();
+		else {
+			VisFrame frame = (VisFrame) getRoot();
+			frame.getInspector().updateOrder();
+		}		
+	}
+	
+	public void addToPropertyStructure(Mark mark) {// TODO...
+		childPropertyStructure.rebuildBindings();
+		
+		if(container instanceof VisBody)
+			((VisBody)container).addToPropertyStructure(mark);
+	}
+	
+	
+	@Override
+	public boolean addToEnd(double x, double y) {
+		if(constraintXProperty.get() != Constraint.None && x < components.get(0).coords.getX()
+				|| constraintYProperty.get() != Constraint.None && y < components.get(0).coords.getY()) {
+			return false;
+		}
+		else return true;
+	}
+	
+	@Override
+	public void addMark(Mark mark, boolean toend) { 
+		mark.container = this;
+	
+		if(toend) {
+			components.add(mark);
+			shapes.getChildren().add(mark.group);
+		}
+		else {
+			components.add(0, mark);
+			shapes.getChildren().add(0, mark.group);
+		}
+		
+		if(mark instanceof VisBody && ((VisBody)mark).getInteractor() != null)
+			((VisBody)mark).getInteractor().redraw();
+	}
+		
+	public void addToGroup(Mark mark) { // TODO....		
+		if(mark instanceof VisBody) childPropertyStructure.addMark(mark, new DefaultSharingStrategy());
+		else childPropertyStructure.addMark(mark);
+				
+		if(container instanceof VisBody)
+			((VisBody)container).addToPropertyStructure(mark);
+		
+		// TODO: These listener should act after the property sharings are activated
+		// Listen to changes of the children nodes
+		mark.coords.x.addListener(this);
+		mark.coords.y.addListener(this);
+		mark.width.addListener(this);
+		mark.height.addListener(this);
+		
+		updateInteractor();		
+	}
+	
+	
+	/*
+	public void removeFromPropertyStructure(Mark mark) {
+		childPropertyStructure.removeNestedMark(mark);
+	}*/
+	
+	public void attachCopy(Mark mark/*, boolean sharedX, boolean sharedY*/) {
+		
+		// Listen to changes of the children nodes
+		mark.coords.x.addListener(this);
+		mark.coords.y.addListener(this);
+		mark.width.addListener(this);
+		mark.height.addListener(this);
+		
+		//mark.coords.xRef.addListener(this);
+		//mark.coords.yRef.addListener(this);
+		
+		updateInteractor();
+	}
+	
+	public void attach(Mark mark, boolean sharedX, boolean sharedY) {
+		Container container = mark.getContainer();
+		container.removeMark(mark);
+	
+		double xpos, ypos;
+		
+		RefX xref = mark.coords.xRef.get();
+		RefY yref = mark.coords.yRef.get();
+
+		if(mark instanceof VisBody) {
+			xpos = mark.getCoords().getX();
+			ypos = mark.getCoords().getY();
+		}
+		else {
+			if(xref == RefX.Left) xpos = mark.left();
+			else if (xref == RefX.Right) xpos = mark.right();
+			else xpos = mark.centerX();
+				
+			if(yref == RefY.Top) ypos = mark.top();
+			else if (yref == RefY.Bottom) ypos = mark.bottom();
+			else ypos = mark.centerY();
+		}
+
+				
+		mark.setPositionCoords(sharedX ? 0 : xpos - coords.getX(), 
+				sharedY ? 0 : ypos - coords.getY());
+						
+		addMark(mark, true);
+		
+		// Listen to changes of the children nodes
+		mark.coords.x.addListener(this);
+		mark.coords.y.addListener(this);
+		mark.width.addListener(this);
+		mark.height.addListener(this);
+	}
+	
+	public void refresh() {
+		refreshID();
+		updateInteractor();
+	}
+	
+	@Override
+	public void removeMark(Mark mark) {
+		if(components.contains(mark)) components.remove(mark); 
+		if(childPropertyStructure != null)
+			childPropertyStructure.removeMark(mark);		
+		
+		refreshID();
+		
+		//stickToYAxis();		
+		//stickToXAxis();
+		//updateInteractor();
+		//updateTreeLayout(components.get(0));
+		
+		if(container instanceof VisBody) {
+			((VisBody)container).removeMark(mark);
+		}
+		
+		refreshID();
+		
+		if(!getComponents().isEmpty()) invalidateControllerAt(0, stickToXAxis(), stickToYAxis());
+	}
+	
+	
+	@Override
+	public void select(MarkSelection  selectedMarks, Shape trace, SelectFilter filter) {
+		if(!filter.accept(selectedMarks.getMarks(), this)) return;
+		
+		if(interactor.intersects(trace)) {	
+			pinX = coords.getX();
+			pinY = coords.getY();				
+			selectedMarks.add(this);
+			
+			return;
+		}
+		else super.select(selectedMarks, trace, filter);
+	}
+	
+		
+	@Override
+	public boolean monoselect(MarkSelection selectedMarks, Circle trace) { // To review how to prioritize its selection or not...	
+		for(int i = components.size() - 1; i >=0; --i) {
+			if(((Mark)components.get(i)).controlselect(selectedMarks, trace)) return true;
+		}
+		
+			
+		// TODO : This is just to improve picking of lines. It's a last-moment hack!!! It need replacement!!!!
+		for(int i = components.size() - 1; i >=0; --i) {
+			Mark mark = (Mark)components.get(i);
+			if(mark instanceof GenericShapeMark && ((GenericShapeMark)mark).shapeProperty.get() == Type.Line && mark.monoselect(selectedMarks, trace)) 
+				return true;
+		}
+		
+	
+		if(interactor.intersects(trace)) {
+			pin();
+			selectedMarks.add(this);
+			return true;
+		}
+		
+		for(int i = components.size() - 1; i >=0; --i) {
+			if(((Mark)components.get(i)).monoselect(selectedMarks, trace)) return true;
+		}
+		
+		return false;
+	}
+	
+	@Override
+	public boolean controlselect(MarkSelection selectedMarks, Circle trace) {	
+		for(int i = components.size() - 1; i >=0; --i) {
+			if(((Mark)components.get(i)).controlselect(selectedMarks, trace)) {
+				return true;
+			}
+		}
+		
+		if(controllerX.intersects(trace) || controllerY.intersects(trace)) {
+			Mark mark = getHighlightedChild();
+						
+			if(mark!=null) {
+				selectedMarks.setDragAccept(false);
+				selectedMarks.add(mark);
+				return true;
+			}
+		}
+		
+		if(interactor.intersectsCenter(trace)) {
+			pinX = coords.getX();
+			pinY = coords.getY();
+			selectedMarks.add(this);
+			return true;
+		}
+		
+		return false;
+	}
+	
+	
+	@Override
+	public void setHighlight(boolean highlight, boolean enableControls) { 
+		this.highlighted = highlight;
+		
+		interactor.setHighlight(highlight);
+		
+		if(container instanceof VisBody) {
+			VisBody vgroup = (VisBody)container;
+			vgroup.highlighted(this, highlight);
+		}		
+	}
+	
+	@Override
+	public String getType() {
+		return "Group";
+	}
+
+	public void dispose() {
+		container.removeMark(this);
+		group.getChildren().clear(); // TODO: Is this OK?
+	}
+	
+		
+	protected void invalidateInteractor() {
+		updateBasicShape();
+		
+		// TODO: I commented that. Is there any reason to exist?
+//		updateInteractor(); 
+//		updateXAxisOrigin();
+//		updateYAxisOrigin();
+		updateInteractor();	
+		
+		updateExtraComponents();
+
+		/*
+		if(container instanceof VisBody) {
+			((VisBody)container).invalidateController(this);
+			((VisBody)container).invalidateInteractor();
+		}*/
+	}
+	
+	protected void invalidateConstraints(Mark mark) {
+		HierarchyPos pos = new HierarchyPos(mark);
+		getRootVirtualGroup().updateTreeLayout(pos);
+		
+		/*
+		int index = Math.max(components.indexOf(mark) - 1, 0);
+		invalidateController(components.get(index));
+		invalidateInteractor();*/
+	}
+		
+	@Override
+	public Mark getHighlightedChild() {
+		if(highlighted) return this;
+		for(Mark mark:components) {
+			if(mark.getHighlightedChild() != null) return mark;
+		}
+		
+		return null;
+		
+	}
+	
+	@Override
+	public boolean isHighlighted() {
+		if(getHighlightedChild() == null) return false;
+		else return true;
+	}
+	
+	@Override
+	public void invalidated(Observable observable) {}
+	
+	
+	//////////////////////////////////////////////////////////////
+	//////////////////////////////////////////////////////////////
+	public boolean stickToYAxis() { 
+		if(components.isEmpty()) return false;
+		if(alignXProperty.get() == YSticky.Yes) {
+			if(constraintXProperty.get() == Constraint.None) {
+				for(Mark mark: components) {
+					mark.coords.x.set(0);
+				}
+			} else { 
+				components.get(0).coords.x.set(0);
+			}
+			return true;
+		} else return false;
+	}
+	
+	public boolean stickToXAxis() {
+		if(components.isEmpty()) return false;		
+		if(alignYProperty.get() == XSticky.Yes) {
+			if(constraintYProperty.get() == Constraint.None) {
+				for(Mark mark: components) {
+					mark.coords.y.set(0);
+				}
+			} else { 
+				components.get(0).coords.y.set(0);
+			}
+			return true;
+		} else return false;
+	}
+	
+	
+	public Mark getMarkAt(HierarchyPos pos) {
+		Integer index = pos.getIndexAt(level - 1);
+		if(index == null) return null;
+		else {
+			Mark mark = components.get(index);
+			if(mark instanceof VisBody) {
+				return ((VisBody)mark).getMarkAt(pos);
+			} else return mark;
+		}
+	}
+	
+	//////////////////////////////////////////////////////////////
+	//////////////////////////////////////////////////////////////
+	// TODO....
+	public void updateLayout(Mark mark) {	
+		if(!toUpdateLayout) return;
+		
+		//Mark mark = (Mark)((Property)observable).getBean();
+		HierarchyPos pos = new HierarchyPos(mark);
+		getRootVirtualGroup().updateTreeLayout(pos);
+		//invalidateControllerAt(components.indexOf(mark));		
+	}
+	
+	
+	// TODO: This works fine although I update everything!!!
+	// I could only update invalidated nodes for higher performance (invisible though)!!!!
+	public void updateTreeLayout(HierarchyPos pos) {
+		boolean stickToY = stickToYAxis();
+		boolean stickToX = stickToXAxis();
+		////////////////////
+		
+		Integer index = pos.getIndexAt(level - 1);
+		
+		if(index == null) return;
+		else if(level > pos.getBottomLevel() && toUpdateLayout) {
+			for(Mark mark: components) {
+				if(mark instanceof VisBody) {
+					((VisBody)mark).updateTreeLayout(pos);
+				}
+			}
+		}
+
+		invalidateControllerAt(index, stickToX, stickToY);
+	}
+	
+	
+	protected void invalidateControllerAt(int index, boolean stickToX, boolean stickToY) {
+		index =  Math.min(components.size() - 1, Math.max(index, 0)); 
+		
+		Mark mark = components.get(stickToY ? 0 : index);
+		controllerX.updateMarkPositions(mark);
+		
+		mark = components.get(stickToX ? 0 : index);
+		controllerY.updateMarkPositions(mark);
+		
+		mark = components.get(index);
+		if(mark.getHighlightedChild() != null) { // TODO: any problems with that?	
+			if(controllerX.isVisible()) controllerX.setMark(mark, true);
+			if(controllerY.isVisible()) controllerY.setMark(mark, true);
+		}
+				
+		invalidateInteractor();
+	}
+	//////////////////////////////////////////////////////////////
+	//////////////////////////////////////////////////////////////
+	
+	
+	public void addToOuterCollection(List<VisBody> list) {
+		VisBody outer = getRootVirtualGroup();
+		if(outer instanceof VisCollection) list.add(outer);
+	}
+	
+	public void addToInnerCollections(List<VisBody> list) {
+		VisBody outer = getRootVirtualGroup();
+		if(outer instanceof VisCollection) {
+			for(Mark mark: outer.components) {
+				if(mark instanceof VisCollection)
+					list.add((VisCollection)mark);
+			}
+			
+			if(list.isEmpty()) list.add(outer);
+		}
+	}
+					
+	public int getLevel() {
+		return level;
+	}
+	
+	@Override
+	public double width() {
+		return interactor.getWidth();
+	}
+
+	@Override
+	public double height() {
+		return interactor.getHeight();
+	}
+	
+	
+	@Override
+	public double getLeft() {
+		return coords.getX() + interactor.left.get();
+	}
+	
+	@Override
+	public double getRight() {
+		return coords.getX() + interactor.right.get();
+	}
+	
+	@Override
+	public double getTop() {
+		return -(coords.getY() - interactor.top.get());
+	}
+	
+	@Override
+	public double getBottom() {
+		return -(coords.getY() - interactor.bottom.get());
+	}
+	
+	
+	@Override
+	public Shadow getShadow(double dx, double dy, double delta) {
+		dx *= delta;
+		dy *= delta;
+		
+		return new Shadow(this, dx, dy, interactor.createCopy(dx, dy));
+	}
+	
+	public Map<PropertyName, Property> getSelfProperties() {
+		Map<PropertyName, Property> map = new TreeMap<>();
+		for(Property property: properties) map.put(new PropertyName(property.getName()), property);
+		return map;
+	}
+	
+	@Override
+	public void stealProperties(SimpleMark mark) {
+		super.stealProperties(mark);
+		if(mark instanceof VisBody) {
+			VisBody vgroup = (VisBody)mark;
+			
+			constraintXProperty.set(vgroup.constraintXProperty.get());
+			constraintXProperty.getPublicProperty().set(vgroup.constraintXProperty.getPublicProperty().get());
+			
+			constraintYProperty.set(vgroup.constraintYProperty.get());
+			constraintYProperty.getPublicProperty().set(vgroup.constraintYProperty.getPublicProperty().get());
+			
+			// TODO:
+			distanceXProperty.getPublicProperty().set(vgroup.distanceXProperty.getPublicProperty().get());
+			distanceYProperty.getPublicProperty().set(vgroup.distanceYProperty.getPublicProperty().get());
+			distanceXProperty.getActiveProperty().set(vgroup.distanceXProperty.getActiveProperty().get());
+			distanceYProperty.getActiveProperty().set(vgroup.distanceYProperty.getActiveProperty().get());
+			
+			distanceXProperty.set(vgroup.distanceXProperty.get());
+			distanceYProperty.set(vgroup.distanceYProperty.get());
+			
+			
+			alignXProperty.set(vgroup.alignXProperty.get());
+			alignXProperty.getPublicProperty().set(vgroup.alignXProperty.getPublicProperty().get());
+			
+			alignYProperty.set(vgroup.alignYProperty.get());
+			alignYProperty.getPublicProperty().set(vgroup.alignYProperty.getPublicProperty().get());
+		}
+	}
+	
+	
+	protected abstract VisBody getInstance(Container container, boolean toEnd);
+	
+	@Override
+	public SimpleMark createCopy(Container container, double dx, double dy) { 
+		double x = coords.getX() + dx;
+		double y = coords.getY() + dy;
+		
+		VisBody vgroup = getInstance(container, container.addToEnd(x, y));
+		vgroup.setLevel(this.level);
+		ReferenceCoords refCoords = new ReferenceCoords(RefX.Left, RefY.Bottom);
+		vgroup.setRefCoords(refCoords);
+		
+		List<Mark> marks = new ArrayList<>();		
+		for(Mark mark: components) {
+			if(mark instanceof SimpleMark) {
+				SimpleMark simpleMark = (SimpleMark)mark;
+				SimpleMark copy = simpleMark.createCopy(vgroup, 0, 0);
+				copy.initProperties();
+				marks.add(copy);
+			}
+		}
+
+		for(Mark mark: marks) {
+			vgroup.attachCopy(mark/*, childPropertyStructure.isXShared(), childPropertyStructure.isYShared()*/);
+		}
+		
+		vgroup.setPropertyStructure(PropertyStructure.create(marks, childPropertyStructure));
+				
+		vgroup.toUpdate(false); // Protect the parent tree from property updates
+		vgroup.stealProperties(this);
+		vgroup.coords.x.set(x);
+		vgroup.coords.y.set(y);
+		vgroup.coords.xRef.set(RefX.Left);
+		vgroup.coords.yRef.set(RefY.Bottom);
+		vgroup.toUpdate(true);
+
+		return vgroup;
+	}
+		
+		
+	public double left() {
+		double left;		
+		left = coords.getX() + interactor.left.get(); // TODO : FREEEEE
+		
+		return left;
+	}
+		
+	public double right() {
+		double right;
+		right = coords.getX() + interactor.right.get(); // TODO : FREEEEE
+		
+		return right;
+	}
+	
+	public double centerX() {
+		double center;
+		center = coords.getX();
+		
+		return center;
+	}
+	
+	public double top() {
+		if(components.size() == 1 || constraintYProperty.get() != DistributionProperty.Constraint.None) {
+			return coords.getY() + components.get(components.size() - 1).top();
+		}
+		else {
+			return coords.getY() - interactor.top.get();
+		}
+	}
+	
+	public double bottom() {		
+		if(components.size() == 1 || constraintYProperty.get() != DistributionProperty.Constraint.None) {
+			return coords.getY() + components.get(0).bottom();
+		}
+		else {
+			return coords.getY() - interactor.bottom.get();
+		}
+	}
+	
+	public double centerY() {
+		double center;
+		center = coords.getY();
+		
+		return center;
+	}
+	
+	@Override
+	public VisBody getRootVirtualGroup() {
+		if(container instanceof VisBody)
+			return ((VisBody) container).getRootVirtualGroup();
+		else return this;
+	}
+	
+	@Override
+	public String getNestingPropertyName(String name) {
+		StringBuffer buffer = new StringBuffer("");
+		
+		buffer.append(PropertyName.getPrefix(level));		
+		buffer.append(name);
+		
+		VisGroup topGroup = getTopGroup();
+		if(topGroup != null && topGroup != this) {
+			String id = createID();
+			String pid = topGroup.createID() + ".";
+			buffer.append(id.replaceAll(pid, ""));			
+		}
+		
+		return buffer.toString();
+	}
+		
+	
+	public boolean isExternal() {
+		return !(container instanceof VisBody);
+	}
+
+	public void highlighted(Mark mark, boolean highlight) {  
+		if(controllerX != null) controllerX.setMark(mark, highlight);
+		if(controllerY != null) controllerY.setMark(mark, highlight);
+		
+		/*
+		if(container instanceof VisBody)
+			((VisBody) container).highlighted(this, highlight);*/
+	}
+
+
+	public void showGroupInteractors(boolean show) {
+		super.showGroupInteractors(show);
+		interactor.setVisible(show);
+	}
+	
+	public VisBody getVirtualGroup() {
+		return this;
+	}
+	
+	@Override
+	public void mouseRelease() { 
+		if(controllerX != null) controllerX.unselectHandle();
+		if(controllerY != null) controllerY.unselectHandle();
+		if(container instanceof VisBody) container.getVirtualGroup().mouseRelease();
+	}
+	
+	
+	@Override
+	public void bringToFront(Mark mark) {
+		if(components.get(components.size()-1) == mark) return;
+		components.remove(mark);
+		components.add(mark);
+
+		shapes.getChildren().remove(mark.group);		
+		shapes.getChildren().add(mark.group);				
+	}
+
+	@Override
+	public void sendToBack(Mark mark) {
+		if(components.get(0) == mark) return;
+		
+		components.remove(mark);
+		components.add(0, mark);
+		
+		shapes.getChildren().remove(mark.group);
+		shapes.getChildren().add(0, mark.group);				
+	}
+	
+	@Override
+	public void updateReordering() {
+		updateReordering(components);
+	}
+
+	public void setPropertyStructure(PropertyStructure propertyStructure) {
+		childPropertyStructure = propertyStructure;
+		childPropertyStructure.setContainer(this);
+	}
+	
+	public boolean hasChildProperties() {
+		return childPropertyStructure != null && !childPropertyStructure.isEmpty();
+	}
+	
+	public PropertyStructure getChildPropertyStructure(){
+		return childPropertyStructure;
+	}
+
+	
+	// TODO: May need to change -- when axes are hidden, not possible to see what's going on
+	public double getControlYPosition() {
+		return 0;
+	}
+	
+	public double getControlXPosition() {
+		return 0;
+	}
+	
+	public void toUpdate(boolean toUpdate) {
+		this.toUpdateLayout = toUpdate;
+	}
+
+	
+	@Override
+	public Property getProperty(PropertyName name) {
+		if(name.isDistributionX()) return constraintXProperty;
+		else if(name.isDistributionY()) return constraintYProperty;
+		else if(name.isDeltaX()) return distanceXProperty;
+		else if(name.isDeltaY()) return distanceYProperty;
+		else if(name.isStickyX()) return alignYProperty;
+		else if(name.isStickyY()) return alignXProperty;
+		else return super.getProperty(name);		
+	}
+}
diff --git a/src/fr/inria/structgraphics/graphics/VisCollection.java b/src/fr/inria/structgraphics/graphics/VisCollection.java
new file mode 100644
index 0000000000000000000000000000000000000000..fac858357e69c6f99c4e5ce9f8dd394c366bc345
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/VisCollection.java
@@ -0,0 +1,142 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import fr.inria.structgraphics.ui.viscanvas.groupings.CollectionPropertyStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.Axis;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.AxisX;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.AxisY;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.BodyInteractor;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.CollectionInteractor;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.LegendCollection;
+import javafx.beans.property.Property;
+
+public class VisCollection extends VisBody {
+
+	protected Axis axisX, axisY;
+	protected LegendCollection legends;
+		
+	public VisCollection(Container parent, boolean toend) {
+		super(parent, toend);
+	}
+
+	protected BodyInteractor createInteractor() { // TODO:...
+		return new CollectionInteractor(this);
+	}
+	
+	public void showVariableOnAxis(DataVariable variable, boolean parent) {
+		if(variable.isX() || variable.isWidth()) {
+			if(parent) axisX.showVariableOnParent(variable);
+			else axisX.showVariable(variable);
+		}
+		else if(variable.isY() || variable.isHeight()) {
+			if(parent) axisY.showVariableOnParent(variable);		
+			else axisY.showVariable(variable);
+		}
+	}
+	
+	
+	@Override
+	public CollectionInteractor getInteractor() {
+		return (CollectionInteractor)interactor;
+	}
+	
+	public void showVariableOnLegend(DataVariable variable) {
+		legends.addLegend(variable);
+	}
+	
+	@Override
+	public void addExtraComponents() {
+		axisX = new AxisX(this);
+		group.getChildren().add(axisX);
+		axisY = new AxisY(this);
+		group.getChildren().add(axisY);
+		legends = new LegendCollection(this);
+		group.getChildren().add(legends);
+	}
+	
+	@Override
+	public void updateExtraComponents() {
+		axisX.update();
+		axisY.update();
+		legends.update();
+	}
+	
+	@Override
+	public String getName() {
+		//return "Collection";
+		return PropertyName.getPrefix(level) + " Collection";
+	}
+	
+	@Override
+	public String getType() {
+		return "Collection";
+	}
+
+	@Override
+	protected VisBody getInstance(Container container, boolean toEnd) {
+		return new VisCollection(container, toEnd);
+	}
+
+	@Override
+	public void addSelfProperties(boolean toCollection, Map<PropertyName, FlexibleListProperty> table) {
+		Collection<FlexibleListProperty> childProperties;
+		if(childPropertyStructure != null) childProperties = ((CollectionPropertyStructure)childPropertyStructure).getProperties().values();
+		else childProperties = new ArrayList<>();
+		
+		if(table.isEmpty()) {
+			for(Property property: properties) {
+				FlexibleListProperty list = FlexibleListProperty.createList(this, property);
+				table.put(new PropertyName(list.getName()), list);
+			}
+			for(Property property: childProperties) {
+				FlexibleListProperty list = FlexibleListProperty.createList(this, property);
+				table.put(new PropertyName(list.getName()), list);
+			}
+		} else {
+			for(Property property: properties) {
+				FlexibleListProperty list  = table.get(new PropertyName(property.getName()));
+				if(list!=null) {
+					if(isFirst()) list.add(0, property);
+					else list.add(property);
+				}
+			}
+			for(Property property: childProperties) {
+				FlexibleListProperty list  = table.get(new PropertyName(property.getName()));
+				if(list!=null) {
+					if(isFirst()) list.add(0, property);
+					else list.add(property);
+				}
+			}
+		}	
+	}
+	
+	@Override
+	public boolean removeSelfProperties(Map<PropertyName, FlexibleListProperty> table) { 
+		boolean removed = super.removeSelfProperties(table);
+		
+		Collection<FlexibleListProperty> childProperties = ((CollectionPropertyStructure)childPropertyStructure).getProperties().values();		
+		for(Property property: childProperties) {
+			FlexibleListProperty list  = table.get(new PropertyName(property.getName()));
+			if(list!=null && list.remove(property)) removed = true;
+		}
+		
+		return removed;
+	}
+	
+	@Override
+	public CollectionPropertyStructure getChildPropertyStructure(){
+		return (CollectionPropertyStructure)super.getChildPropertyStructure();
+	}
+
+	public void addID(List<Property> ids, int level) {
+		if(level == this.level) ids.add(id);
+		else if(container instanceof VisCollection) ((VisCollection)container).addID(ids, level);
+	}
+}
diff --git a/src/fr/inria/structgraphics/graphics/VisFrame.java b/src/fr/inria/structgraphics/graphics/VisFrame.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ac954f3a6eebbe40370d2835a8d10f8dfd8b4fa
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/VisFrame.java
@@ -0,0 +1,167 @@
+package fr.inria.structgraphics.graphics;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.FillColorProperty;
+import fr.inria.structgraphics.types.HeightProperty;
+import fr.inria.structgraphics.types.StrokeColorProperty;
+import fr.inria.structgraphics.types.WidthProperty;
+import fr.inria.structgraphics.ui.inspector.InspectorView;
+import javafx.beans.property.DoubleProperty;
+import javafx.geometry.Point2D;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Rectangle;
+
+public class VisFrame extends Container {
+		
+	public DoubleProperty width, height;
+	protected FillColorProperty paint = new FillColorProperty(this);
+	public StrokeColorProperty stroke = new StrokeColorProperty(this);
+	private Rectangle frame;
+	
+	private InspectorView inspector;
+	
+	private Rectangle bedsheet = null;
+	
+	public VisFrame(double width, double height){
+		super();
+		
+		this.width = new WidthProperty(this, width);
+		this.height = new HeightProperty(this, height);
+				
+		frame = new Rectangle(0, 0, width, height); // Bind with rectangle's dimensions
+		this.width.bindBidirectional(frame.widthProperty());
+		this.height.bindBidirectional(frame.heightProperty());
+		
+	//	paint.set(Color.web("#f1f1e8"));
+		paint.set(Color.WHITE);
+		frame.setFill(paint.get());
+		
+		stroke.set(Color.GREY);
+
+		group.getChildren().add(frame);		
+	}
+		
+	@Override
+	public void initProperties() {
+		addProperty(this.width);
+		addProperty(this.height);
+		addProperty(this.paint);
+		addProperty(this.stroke);
+		//super.initProperties();
+	}
+		
+	public void setInspector(InspectorView inspector) {
+		this.inspector = inspector;
+	}
+	
+	public InspectorView getInspector() {
+		return inspector;
+	}
+	
+	@Override
+	public Point2D getReferencePoint(double cx, double cy) {
+		double x, y;
+		
+		if(refCoords.containerXRef.get() == RefX.Left) x = cx; 
+		else if(refCoords.containerXRef.get() == RefX.Right) x = width.get() + cx; 
+		else x = width.get()/2 + cx;
+		
+		if(refCoords.containerYRef.get() == RefY.Top) y = -cy; 
+		else if(refCoords.containerYRef.get() == RefY.Bottom) y = height.get() - cy; 
+		else y = height.get()/2 - cy;
+		
+		return new Point2D(x, y);
+	}
+	
+	@Override
+	public double getRefAngle(double x) {
+		return 0;
+	}
+	
+	@Override
+	public String getName() {
+		return "Root Frame";
+	}
+
+	@Override
+	public String getType() {
+		return "Pane";
+	}
+
+
+	@Override
+	public void updateShape() {
+		frame.setFill(paint.get());
+	}
+
+
+	public double getRootWidth() {
+		return width.get();
+	}
+	
+	public double getRootHeight() {
+		return height.get();
+	}
+
+	@Override
+	public void bringToFront(Mark mark) {
+		if(components.get(components.size()-1) == mark) return;
+		
+		components.remove(mark);
+		components.add(mark);
+
+		group.getChildren().remove(mark.group);
+		group.getChildren().add(mark.group);			
+	}
+
+	@Override
+	public void sendToBack(Mark mark) {
+		if(components.get(0) == mark) return;
+		
+		components.remove(mark);
+		components.add(0, mark);
+		
+		group.getChildren().remove(mark.group);
+		group.getChildren().add(1, mark.group);		
+	}
+	
+	@Override
+	public void updateReordering() {
+		for(Mark mark:components) mark.refreshID();
+		getInspector().updateOrder();
+	}	
+	
+	public Rectangle createBedSheet() {
+		if(bedsheet == null) {
+			bedsheet = new Rectangle(0, 0, width.get(), height.get());
+			bedsheet.setFill(Color.rgb(255, 255, 255, 0.6)); 			
+		} else {
+			bedsheet.setWidth(width.get());
+			bedsheet.setHeight(height.get());
+		}
+
+		return bedsheet;
+	}
+	
+	public Rectangle getBedSheet() {
+		return bedsheet;
+	}
+	
+	@Override
+	public ShapeMark getShape(double x, double y) {
+		for(Mark mark: components) {
+			if(mark instanceof LineConnectedCollection) { // Only consider the shapes somewhere within collections
+				double x_ = x - mark.coords.getX();
+				double y_ = (height.get() - y) - mark.coords.getY();
+				
+				ShapeMark mark_ = mark.getShape(x_, y_);
+				if(mark_ != null) return mark_;				
+			}
+		}
+				
+		return null;
+	}
+}
+
diff --git a/src/fr/inria/structgraphics/graphics/VisGroup.java b/src/fr/inria/structgraphics/graphics/VisGroup.java
new file mode 100644
index 0000000000000000000000000000000000000000..382cd51d2a9cc1f4f74f36a12145fa63107be19b
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/VisGroup.java
@@ -0,0 +1,309 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.Shareable;
+import fr.inria.structgraphics.types.XProperty;
+import fr.inria.structgraphics.types.YProperty;
+import fr.inria.structgraphics.types.AlignmentProperty.XSticky;
+import fr.inria.structgraphics.types.AlignmentProperty.YSticky;
+import fr.inria.structgraphics.ui.utils.GroupBinding;
+import fr.inria.structgraphics.ui.viscanvas.groupings.CollectionPropertyStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupings.GroupPropertyStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.BodyInteractor;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.CollectionInteractor;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.GroupInteractor;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.SimpleGroupInteractor;
+import javafx.beans.property.Property;
+import javafx.scene.shape.Line;
+
+public class VisGroup extends VisBody {
+
+	protected ArrayList<Property> allProperties;
+	
+	public VisGroup(Container parent, boolean toend) {
+		super(parent, toend);
+		// TODO Auto-generated constructor stub
+	}
+	
+	@Override
+	public String getName() {
+		return PropertyName.getPrefix(level) + " Group";
+	}
+	
+	protected BodyInteractor createInteractor() { // TODO:...
+		return new GroupInteractor(this);
+	}
+
+	@Override
+	protected VisBody getInstance(Container container, boolean toEnd) {
+		return new VisGroup(container, toEnd);
+	}
+	
+	@Override
+	public BodyInteractor getInteractor() {
+		return interactor;
+	}
+	
+	@Override
+	public void addLeafIDs(List<Property> ids){
+		ids.add(id);
+	}
+	
+	@Override
+	public void addIDs(List<Property> ids, int level) {
+		if(this.level == level) ids.add(id);
+		else if(container instanceof VisCollection) ((VisCollection)container).addID(ids, level);
+	}
+	
+	@Override
+	public int leafs() {
+		return 1;
+	}
+	
+	@Override
+	public int getBottomLevel() {
+		return level;
+	}
+	
+	@Override
+	public void addSelfProperties(boolean toCollection, Map<PropertyName, FlexibleListProperty> table) {
+		
+		if(toCollection) {
+			for(Property property: allProperties) {				
+				FlexibleListProperty list  = table.get(new PropertyName(property.getName()));
+				if(list!=null) {
+					if(isFirst()) list.add(0, property);
+					else list.add(property);
+				}
+				else {
+					list = FlexibleListProperty.createList(this, property, true);
+					table.put(new PropertyName(property.getName()), list);
+				}
+			}			
+		} else {	
+			Collection<FlexibleListProperty> childProperties;
+			if(childPropertyStructure != null) childProperties = ((GroupPropertyStructure)childPropertyStructure).getProperties().values();
+			else childProperties = new ArrayList<>();
+			
+			for(Property property: properties) {
+				FlexibleListProperty list  = table.get(new PropertyName(PropertyName.getCleanName(property.getName())));
+				
+				if(list!=null) {
+					if(isFirst()) list.add(0, property);
+					else list.add(property);
+				}
+				else {
+					list = FlexibleListProperty.createList(this, property);
+					table.put(new PropertyName(list.getName()), list);
+				}
+			}
+			for(FlexibleListProperty property: childProperties) {				
+				FlexibleListProperty list  = table.get(new PropertyName(property.getName()));
+
+				if(list!=null) {
+					if(isFirst()) list.addEach(0, property.flatten());
+					else list.addEach(property.flatten());
+				}
+				else {
+					list = FlexibleListProperty.createList(this, property.flatten());
+					table.put(new PropertyName(property.getName()), list);					
+				}
+			}
+		}
+	}
+	
+	
+	@Override
+	public boolean removeSelfProperties(Map<PropertyName, FlexibleListProperty> table) { // TODO: Check what need to be done!!!!
+		boolean removed = super.removeSelfProperties(table);
+		
+		Collection<FlexibleListProperty> childProperties = ((GroupPropertyStructure)childPropertyStructure).getProperties().values();		
+		for(Property property: childProperties) {
+			FlexibleListProperty list  = table.get(new PropertyName(property.getName()));
+			if(list!=null && list.remove(property)) removed = true;
+		}
+		
+		return removed;
+	}
+	
+	@Override
+	public void initVisibility() {
+		super.initVisibility();
+		
+		for(Property property:properties) { // TODO: CHECK for nested groups !!!
+			if(property instanceof Shareable) {
+				PropertyName name = new PropertyName(property.getName());
+				((Shareable)property).getPublicProperty().set(name.isX() || name.isY());
+			}
+		}
+	}
+	
+	@Override
+	public void initProperties() {		
+		super.initProperties();
+		
+		ArrayList<Property> publicProperties = new ArrayList<>();
+		ArrayList<Property> allProperties = new ArrayList<>();
+    	splitProperties(publicProperties, allProperties);
+	}
+	
+	@Override
+	public SimpleMark createCopy(Container container, double dx, double dy) { // TODO: Correct?
+		VisGroup copy = (VisGroup)super.createCopy(container, dx, dy);
+    	
+		return copy;
+	}
+	
+	@Override
+	public void pin() {
+		if(container instanceof VisGroup) {
+			super.pin();
+			for(Mark child: getComponents()) { 
+				child.pin();				
+			}
+		}
+		else super.pin();
+	}
+	
+	public void setPositionX(double x) {
+		/*if(container instanceof VisGroup) {
+			translateAllBy(x, 0);
+		} else*/ coords.x.set(x);		
+	}
+
+	public void setPositionY(double y) {
+		/*if(container instanceof VisGroup) {
+			translateAllBy(0, y);
+		} else*/ coords.y.set(y);		
+	}
+		
+		
+	// Makes sure that all are translated by dx, dy without undesirable binding activations 
+	protected void translateAllBy(double dx, double dy) {
+		for(Mark child: getComponents()) {
+			child.setTentative(child.coords.getX() + dx, child.coords.getY() +  dy);
+		}
+		
+		for(Mark child: getComponents()) {
+			child.validateTentative();
+		}
+	}
+	
+	// Makes sure that all are translated by dx, dy without undesirable binding activations 
+	protected void translateAll(Line lineTrace) {
+		double dx = lineTrace.getEndX() - lineTrace.getStartX();
+		double dy = -lineTrace.getEndY() + lineTrace.getStartY();
+		for(Mark child: getComponents()) {
+			child.setTentative(child.pinX + dx, child.pinY + dy);
+		}
+		
+		for(Mark child: getComponents()) {
+			child.validateTentative();
+		}
+	}
+	
+	@Override
+	public void attach(Mark mark, boolean sharedX, boolean sharedY) {
+		Container container = mark.getContainer();
+		container.removeMark(mark);
+		
+		//////////
+		for(Property property:mark.properties) {
+			if(property instanceof Shareable) {
+				if(mark instanceof VisGroup) {
+					if(property instanceof XProperty || property instanceof YProperty) ((Shareable)property).getPublicProperty().set(false);
+				}
+				else ((Shareable)property).getPublicProperty().set(false);
+			}
+		}
+		
+		double xpos, ypos;
+		
+		RefX xref = mark.coords.xRef.get();
+		RefY yref = mark.coords.yRef.get();
+
+		if(xref == RefX.Left) xpos = mark.left();
+		else if (xref == RefX.Right) xpos = mark.right();
+		else xpos = mark.centerX();
+			
+		if(yref == RefY.Top) ypos = mark.top();
+		else if (yref == RefY.Bottom) ypos = mark.bottom();
+		else ypos = mark.centerY();
+		
+		mark.setPositionCoords(sharedX ? 0 : xpos - coords.getX(), sharedY ? 0 : ypos - coords.getY());
+		/////////
+						
+		addMark(mark, true);		
+	}
+			
+	@Override
+	public GroupPropertyStructure getChildPropertyStructure(){
+		return (GroupPropertyStructure)super.getChildPropertyStructure();
+	}
+	
+	
+	@Override
+	public VisGroup getTopGroup() {
+		if(container instanceof VisGroup) return ((VisGroup) container).getTopGroup();
+		else return this;
+	}
+	
+	public boolean isTopGroup() {
+		if(container instanceof VisGroup) return false;
+		else return true;
+	}
+	
+	public void splitProperties(ArrayList<Property> publicProperties, ArrayList<Property> allProperties) {		
+		Collection<Property> selfProperties = getSelfProperties().values();
+		for(Property prop:selfProperties) {
+			if(prop instanceof Shareable) {
+				allProperties.add(prop);
+				if(((Shareable)prop).getPublicProperty().get()) publicProperties.add(prop);
+			}
+		}
+		
+		// Children properties???
+		Collection<FlexibleListProperty> childproperties = childPropertyStructure.getProperties().values();
+		// TODO: ????
+		for(FlexibleListProperty props: childproperties) {
+			PropertyName name = props.getPropertyName();
+			if(childPropertyStructure.getCommon().contains(name)) {				
+				ArrayList<GroupBinding> groups = ((GroupPropertyStructure)childPropertyStructure).getGroups(name);
+				if(groups != null) {
+					for(GroupBinding group: groups) {
+						if(!group.isEmpty()) {
+							Property first = group.firstProperty();
+							if(((Shareable)first).getPublicProperty().get()) publicProperties.add(first);
+							for(Property property: (ArrayList<Property>)group.getProperties()) {						
+								allProperties.add(property);
+								((Shareable)property).getHiddenProperty().set(property != first);
+							}							
+						}
+					}
+				}
+			} else {
+				for(Property prop: props.getValue()) {
+					if(prop instanceof Shareable) {
+						((Shareable)prop).getHiddenProperty().set(false);
+						allProperties.add(prop);
+						if(((Shareable)prop).getPublicProperty().get()) publicProperties.add(prop);
+					}
+				}
+			}
+		}
+		
+		this.allProperties = allProperties;
+	}
+	
+	public ArrayList<Property> getAllProperties(){
+		return allProperties;
+	}
+}
diff --git a/src/fr/inria/structgraphics/graphics/XMarkComparator.java b/src/fr/inria/structgraphics/graphics/XMarkComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c15433196289062191a86cddade8cb3b111c25f
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/XMarkComparator.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.Comparator;
+
+public class XMarkComparator implements Comparator<Mark> {
+
+	@Override
+	public int compare(Mark mark1, Mark mark2) {
+		return ((Double)mark1.coords.x.get()).compareTo((Double)mark2.coords.x.get());
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/graphics/YMarkComparator.java b/src/fr/inria/structgraphics/graphics/YMarkComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2a549d70acae27b304f3dd9c8131971a12a6a1c
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/YMarkComparator.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.graphics;
+
+import java.util.Comparator;
+
+public class YMarkComparator implements Comparator<Mark> {
+
+	@Override
+	public int compare(Mark mark1, Mark mark2) {
+		return ((Double)mark1.coords.y.get()).compareTo((Double)mark2.coords.y.get());
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/graphics/controls/Control.java b/src/fr/inria/structgraphics/graphics/controls/Control.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e9155707cdcc79f60a04be55804fea6357dd84a
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/controls/Control.java
@@ -0,0 +1,73 @@
+package fr.inria.structgraphics.graphics.controls;
+
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.shape.Shape;
+
+public class Control extends Rectangle {
+	private final static double SIZE = 6;
+		
+	protected ControlListener listener;
+	
+	public Control() {
+		super(SIZE, SIZE);		
+		setStroke(Color.GRAY);
+		setStrokeWidth(0.5);
+		setFill(Color.rgb(255, 255, 255, 0.5));
+	}
+	
+	public double centerX() {
+		return getX() + getWidth()/2;
+	}
+	
+	public double centerY() {
+		return getY() + getWidth()/2;
+	}
+	
+	public void moveTo(double x, double y) {
+		xProperty().set(x - getWidth()/2);
+		yProperty().set(y - getWidth()/2);
+	}
+	
+	public boolean intersects(Shape trace) {
+		if(trace == null) return false;
+		Shape intersection = Shape.intersect(this, trace);
+		if(!(intersection instanceof Path) || !((Path)intersection).getElements().isEmpty()) 
+			return true;
+		else return false;
+	}
+
+	public void setControlListener(ControlListener listener) {
+		this.listener = listener;
+	}
+	
+	public void pin() {
+		if(listener!=null) listener.pin();
+	}
+	
+	public void drag(Line lineTrace) {
+		if(listener!=null) listener.drag(lineTrace);
+	}
+	
+	
+	public interface ControlListener {
+		public void drag(Line lineTrace);
+		public void pin();
+		public void offsetX(double offset);
+		public void offsetY(double offset);
+	}
+
+
+	public void offsetXPin(double offset) {
+		if(listener!=null) listener.offsetX(offset);
+	}
+	
+	public void offsetYPin(double offset) {
+		if(listener!=null) listener.offsetY(offset);
+	}
+
+}
+
+
diff --git a/src/fr/inria/structgraphics/graphics/splines/CubicSpline.java b/src/fr/inria/structgraphics/graphics/splines/CubicSpline.java
new file mode 100644
index 0000000000000000000000000000000000000000..4431d357e91033fbf43da032198475f5e936cbab
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/splines/CubicSpline.java
@@ -0,0 +1,229 @@
+package fr.inria.structgraphics.graphics.splines;
+
+import java.awt.geom.Path2D;
+import java.util.ArrayList;
+import java.util.List;
+
+import javafx.geometry.Point2D;
+import javafx.scene.shape.CubicCurveTo;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Shape;
+
+/**
+ * A cubic spline.
+ * @author Theophanis Tsandilas
+ */
+public class CubicSpline {
+
+	private List<Vector2D> backwardTangents = new ArrayList<Vector2D>();
+	private List<Point2D> controlPoints = new ArrayList<Point2D>();
+	private List<Vector2D> forwardTangents = new ArrayList<Vector2D>();
+	private Path linePath;
+	private Path path;
+	private List<Point2D> pathPoints = new ArrayList<Point2D>();
+	
+	private Path2D awtpath; // Used to flatten the curve (not available methods in FX)
+
+	// .3 is pretty good...
+	private double tension = .3;
+	
+	
+	public CubicSpline() {
+		path = new Path();
+	}
+	
+	public CubicSpline(Path path) {
+		this.path = path;
+	}
+	
+	public void clear(){
+		backwardTangents.clear();
+		controlPoints.clear();
+		forwardTangents.clear();
+		linePath = new Path();
+		path.getElements().clear();
+		awtpath = new Path2D.Double();
+		
+		pathPoints.clear();
+	}
+	
+	public List<Vector2D> getBackwardTangents() {
+		return backwardTangents;
+	}
+
+	public List<Point2D> getControlPoints() {
+		return controlPoints;
+	}
+
+	/**
+	 * @return
+	 */
+	public List<Vector2D> getForwardTangents() {
+		return forwardTangents;
+	}
+
+	/**
+	 * @return
+	 */
+	public Shape getLineShape() {
+		return linePath;
+	}
+
+	/**
+	 * @return a copy of the path's points
+	 */
+	public List<Point2D> getPathPoints() {
+		return pathPoints;
+	}
+
+	/**
+	 * @return
+	 */
+	public Shape getShape() {
+		return path;
+	}
+	
+	/**
+	 * Connect the points into line segments.
+	 * 
+	 * @param points
+	 */
+	private void makeConnectedLines() {
+		Point2D p;
+		
+		if(pathPoints.size() > 0) {
+			p = pathPoints.get(0);
+			linePath.getElements().add(new MoveTo(p.getX(), p.getY()));
+		}
+		
+		for (int i = 1; i < pathPoints.size(); i++) {
+			p = pathPoints.get(i);
+			linePath.getElements().add(new LineTo(p.getX(), p.getY()));
+		}
+	}
+
+	/**
+	 * 
+	 */
+	private void makePiecewiseBezier() {
+		//path.getElements().clear();
+
+		Point2D p1, c1, c2, p2;
+				
+		int j = 0; // control points index
+		for (int i = 0; i < pathPoints.size() - 1; i++) {
+			p1 = pathPoints.get(i);
+			c1 = controlPoints.get(j++); // get j, and increment it
+			c2 = controlPoints.get(j++);
+			p2 = pathPoints.get(i + 1);
+
+			if(i == 0) path.getElements().add(new MoveTo(p1.getX(), p1.getY()));
+			path.getElements().add(new CubicCurveTo(c1.getX(), c1.getY(), c2.getX(), c2.getY(), p2.getX(), p2.getY()));
+			
+			// AWT object
+			awtpath.moveTo(p1.getX(), p1.getY());
+			awtpath.curveTo(c1.getX(), c1.getY(), c2.getX(), c2.getY(), p2.getX(), p2.getY());
+		}		
+	}
+	
+	/**.
+	 * 
+	 * @param points
+	 */
+	public void setPoints(List<Point2D> points) {
+		if(points == null || points.size() == 0) return;
+	
+		clear();
+			
+		pathPoints.addAll(points);
+
+		// if a single point, draw a dot
+		if (points.size() == 1) {
+			final Point2D point = points.get(0);
+			path.getElements().add(new MoveTo(point.getX(), point.getY()));
+			path.getElements().add(new LineTo(point.getX(), point.getY()));
+			
+			// AWT object
+			awtpath.moveTo(point.getX(), point.getY());
+			awtpath.lineTo(point.getX(), point.getY());
+		}
+		// if two points, draw a line segment
+		else if (points.size() == 2) { 	
+			final Point2D point1 = points.get(0);
+			final Point2D point2 = points.get(1);
+			path.getElements().add(new MoveTo(point1.getX(), point1.getY()));
+			path.getElements().add(new LineTo(point2.getX(), point2.getY()));
+			
+			// AWT object
+			awtpath.moveTo(point1.getX(), point1.getY());
+			awtpath.lineTo(point2.getX(), point2.getY());
+			return;
+		}
+		else {
+			// if three points or more, do the piecewise business...
+			// construct piecewise cubic bezier curves that generate the catmull-rom
+
+			// tack on an extra last point, to enable the calculation of the last tangent
+			Point2D pSecondToLast = points.get(points.size() - 2);
+			Point2D pLast = points.get(points.size() - 1);
+			points.add(Vector2D.add(pLast, Vector2D.subtract(pLast, pSecondToLast)));
+
+			// p0 is the previous point
+			Point2D p0 = Vector2D.add(points.get(0), Vector2D.subtract(points.get(0), points.get(1)));
+			// p1 is the current point
+			Point2D p1 = points.get(0);
+			// p2 is the next point
+			Point2D p2;
+
+			// add tangents and control points
+			for (int i = 0; i < points.size() - 1; i++) {
+				p2 = points.get(i + 1);
+
+				// === Backwards ===
+				// add a backward tangent for each point, equal to the point before minus the point
+				// after
+				final Vector2D bkwd = Vector2D.getScaled(tension * Vector2D.subtract(p0, p1).magnitude(),
+						Vector2D.subtract(p0, p2));
+				backwardTangents.add(bkwd);
+
+				// make a backward control point by adding it to the current point
+				controlPoints.add(Vector2D.add(p1, bkwd));
+
+				// === Forwards ===
+				// add a tangent for each point, that is equal to the point after minus the point before
+				// length is equal to half the distance to the next point
+				final Vector2D fwd = Vector2D.getScaled(tension * Vector2D.subtract(p2, p1).magnitude(), Vector2D
+						.subtract(p2, p0));
+				forwardTangents.add(fwd);
+
+				// make a forward control point by adding it to the current point
+				controlPoints.add(Vector2D.add(p1, fwd));
+
+				// shift the points over
+				p0 = p1;
+				p1 = p2;
+			}
+
+			// delete first and last control points (as they are useless)
+			controlPoints.remove(0);
+			controlPoints.remove(controlPoints.size() - 1);
+
+			// don't remove tangents
+
+			// line segments
+			makeConnectedLines();
+
+			// general path, piecewise cubic bezier
+			makePiecewiseBezier();
+		}
+		
+	}
+
+	public FlattenedPath getFlattenedPath() {
+		return new FlattenedPath(awtpath);
+	}
+
+}
+
diff --git a/src/fr/inria/structgraphics/graphics/splines/FlattenedPath.java b/src/fr/inria/structgraphics/graphics/splines/FlattenedPath.java
new file mode 100644
index 0000000000000000000000000000000000000000..d6f119861d1a9a548d7f281d0ba60fe99fa783b5
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/splines/FlattenedPath.java
@@ -0,0 +1,111 @@
+package fr.inria.structgraphics.graphics.splines;
+
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
+import java.util.ArrayList;
+
+import javafx.geometry.Point2D;
+
+public class FlattenedPath {
+
+	private final static double FLATNESS = 1; // maximum error for flattening the curve
+	
+	private ArrayList<Line2D> segments = new ArrayList<Line2D>();
+	private ArrayList<Double> cumlength = new ArrayList<Double>(); // Cumulative length
+	private ArrayList<Double> angles = new ArrayList<Double>(); // In radius (not in degrees)
+	
+	private double length = 0;
+	
+	public FlattenedPath(Path2D awtPath) {		
+		PathIterator pathIterator = awtPath.getPathIterator(null, FLATNESS);
+		double[] coords = new double[6];
+				
+		double x = 0, y = 0;
+		for( ; !pathIterator.isDone(); pathIterator.next()) {
+			int type = pathIterator.currentSegment(coords);
+			
+			if(type == PathIterator.SEG_MOVETO) {
+				x = coords[0];
+				y = coords[1];
+			}
+			else {
+				Line2D segment = new Line2D.Double(x, y, coords[0], coords[1]);
+				double dist = segment.getP1().distance(segment.getP2());
+				
+				x = coords[0];
+				y = coords[1];
+	
+				segments.add(segment);
+				cumlength.add(length);
+				length += dist;
+
+				angles.add(calculateAngle(segment));
+			}
+		}
+	}
+	
+	public FlattenedPath(ArrayList<Point2D> points) {
+		for(int i = 1; i < points.size(); ++i) {
+			Line2D segment = new Line2D.Double(points.get(i - 1).getX(), points.get(i - 1).getY(), 
+					points.get(i).getX(), points.get(i).getY());
+			double dist = segment.getP1().distance(segment.getP2());
+		
+			segments.add(segment);
+			cumlength.add(length);
+			length += dist;
+
+			angles.add(calculateAngle(segment));
+		}
+	}
+
+	public double getLength() {
+		return length;
+	}
+		
+	private double calculateAngle(Line2D segment) {
+		return Math.atan2(segment.getY1() - segment.getY2(), segment.getX2() - segment.getX1());
+	}
+	
+	private int getIndex(double l) {
+		if(cumlength.size() == 0) return -1;
+		else if(cumlength.size() == 1) return 0;
+		
+		for(int i = 1; i < cumlength.size(); ++i)
+			if(l < cumlength.get(i)) return i - 1;
+		
+		return cumlength.size() - 1;
+	}
+	
+	private double getLength(int index) {
+		if(index == cumlength.size() - 1) 
+			return length - cumlength.get(index);
+		else return cumlength.get(index + 1) - cumlength.get(index);
+	}
+	
+	public double getAngleInDegrees(double l) {
+		return Math.toDegrees(getAngleInRads(l));
+	}
+	
+	public double getAngleInRads(double l) {
+		int index = getIndex(l);
+		
+		if(index == -1) return 0;
+		else return angles.get(index);		
+	}
+	
+	public Point2D getPoint(double l) {
+		int index = getIndex(l);
+		if(index == -1) return null;
+		
+		double x0 = segments.get(index).getX1();
+		double y0 = segments.get(index).getY1();
+		double x1 = segments.get(index).getX2();
+		double y1 = segments.get(index).getY2();
+				
+		double ratio = (l - cumlength.get(index))/getLength(index);
+		
+		return new Point2D(x0 + ratio*(x1 - x0), y0 + ratio*(y1 - y0));
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/graphics/splines/Vector2D.java b/src/fr/inria/structgraphics/graphics/splines/Vector2D.java
new file mode 100644
index 0000000000000000000000000000000000000000..69fd251c1c5dc4c5f49549cc5ab0d837dabaca4d
--- /dev/null
+++ b/src/fr/inria/structgraphics/graphics/splines/Vector2D.java
@@ -0,0 +1,118 @@
+/**
+ * 
+ */
+package fr.inria.structgraphics.graphics.splines;
+
+import javafx.geometry.Point2D;
+
+/**
+ *taken from PaperToolkit.
+ */
+public class Vector2D {
+
+	/**
+	 * Adds a vector to a point, resulting in a new point.
+	 * 
+	 * @param p
+	 * @param v
+	 * @return
+	 */
+	public static Point2D add(Point2D p, Vector2D v) {
+		return new Point2D(p.getX() + v.x, p.getY() + v.y);
+	}
+
+	/**
+	 * @param a
+	 * @param b
+	 * @return
+	 */
+	public static Vector2D add(Vector2D a, Vector2D b) {
+		final Vector2D result = new Vector2D();
+		result.x = a.x + b.x;
+		result.y = a.y + b.y;
+		return result;
+	}
+
+	/**
+	 * @return
+	 */
+	public static Vector2D getNormalized(Vector2D v) {
+		return getScaled(1.0, v);
+	}
+
+	/**
+	 * @param desiredMagnitude
+	 * @return
+	 */
+	public static Vector2D getScaled(double desiredMagnitude, Vector2D v) {
+		final double scaleFactor = desiredMagnitude / v.magnitude();
+		final double newX = v.x * scaleFactor;
+		final double newY = v.y * scaleFactor;
+		return new Vector2D(newX, newY);
+	}
+
+	/**
+	 * @param d
+	 * @param vector2D
+	 * @return
+	 */
+	public static Vector2D multiply(double d, Vector2D vector2D) {
+		return new Vector2D(vector2D.x * d, vector2D.y * d);
+	}
+
+	/**
+	 * Returns a - b.
+	 * 
+	 * @param a
+	 * @param b
+	 * @return
+	 */
+	public static Vector2D subtract(Point2D a, Point2D b) {
+		final Vector2D result = new Vector2D();
+		result.x = a.getX() - b.getX();
+		result.y = a.getY() - b.getY();
+		return result;
+	}
+
+	/**
+	 * The X component.
+	 */
+	private double x = 0;
+
+	/**
+	 * The Y component.
+	 */
+	private double y = 0;
+
+	public Vector2D() {
+
+	}
+
+	/**
+	 * @param d
+	 * @param e
+	 */
+	public Vector2D(double _x, double _y) {
+		x = _x;
+		y = _y;
+	}
+
+	public double getX() {
+		return x;
+	}
+
+	/**
+	 * @return
+	 */
+	public double getY() {
+		return y;
+	}
+
+	/**
+	 * @return
+	 */
+	public double magnitude() {
+		return Math.sqrt(x * x + y * y);
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/persistence/JsonDescription.java b/src/fr/inria/structgraphics/persistence/JsonDescription.java
new file mode 100644
index 0000000000000000000000000000000000000000..f03f40372c7a8e8db9eff9beac3a83b1ded63cd2
--- /dev/null
+++ b/src/fr/inria/structgraphics/persistence/JsonDescription.java
@@ -0,0 +1,61 @@
+package fr.inria.structgraphics.persistence;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+
+public class JsonDescription {		
+	private JsonObject visObject;
+		
+	public JsonDescription(File file) {
+		Path path = Paths.get(file.getPath());
+		
+		StringBuffer textContent = new StringBuffer();
+		List<String> lines;
+		try {
+			lines = Files.readAllLines(path,  Charset.forName("ISO-8859-1"));
+			
+			for (String line : lines) {
+				textContent.append(line + "\n");
+			}
+			
+			JsonReader reader = Json.createReader(new StringReader(textContent.toString()));
+			visObject = reader.readObject();
+			reader.close();
+		} catch (IOException e) {
+			visObject = null;
+		}
+	}
+			
+	public boolean isWorkspace() {
+		return visObject.containsKey("workspace");
+	}
+	
+	public boolean isLibrary() {
+		return visObject.containsKey("library");
+	}
+	
+	public JsonArray getVisArray(boolean workspace) {
+		if(visObject == null) return null;
+		else return workspace ? visObject.getJsonObject("workspace").getJsonArray("visualizations") : visObject.getJsonArray("visualizations");
+	}
+	
+	public JsonArray getLibraryArray(boolean workspace) {
+		if(visObject == null) return null;
+		else return workspace ? visObject.getJsonObject("workspace").getJsonArray("library") : visObject.getJsonArray("library");
+	}
+	
+	public JsonArray getSpreadsheetArray() {
+		return visObject.getJsonObject("workspace").getJsonArray("datasheet");
+	}
+}
diff --git a/src/fr/inria/structgraphics/persistence/JsonObjectReader.java b/src/fr/inria/structgraphics/persistence/JsonObjectReader.java
new file mode 100644
index 0000000000000000000000000000000000000000..cab2af2b2012c1f8583d025bf72e452b99decf0d
--- /dev/null
+++ b/src/fr/inria/structgraphics/persistence/JsonObjectReader.java
@@ -0,0 +1,347 @@
+package fr.inria.structgraphics.persistence;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import javax.json.JsonValue.ValueType;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.GenericShapeMark;
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.PositionCoords;
+import fr.inria.structgraphics.graphics.ReferenceCoords;
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.graphics.TextualMark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.ColoringSchemeProperty;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.LineTypeProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.types.Shareable;
+import fr.inria.structgraphics.types.AlignmentProperty.XSticky;
+import fr.inria.structgraphics.types.AlignmentProperty.YSticky;
+import fr.inria.structgraphics.types.ColoringSchemeProperty.Scheme;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import fr.inria.structgraphics.types.ShapeProperty.Type;
+import fr.inria.structgraphics.ui.utils.GroupBinding;
+import fr.inria.structgraphics.ui.viscanvas.groupings.CollectionPropertyStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnection;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnections;
+import fr.inria.structgraphics.ui.viscanvas.groupings.GroupPropertyStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupings.PropertyStructure;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.scene.paint.Paint;
+
+public class JsonObjectReader {
+
+	public static ArrayList<Mark> readChildrenFromJasonArray(Container parent, JsonArray jsonArray) {
+		ArrayList<Mark> marks = new ArrayList<>();
+		
+		for(int i = 0; i < jsonArray.size(); ++i) {
+			JsonValue jsonObject = jsonArray.get(i);
+			
+			if(jsonObject instanceof JsonObject) {
+				Mark mark = readFromJasonObject(parent, (JsonObject)jsonObject);
+				if(mark != null) marks.add(mark);
+			}
+		}
+		
+		return marks;
+	}
+
+	public static Mark readFromJasonObject(Container parent, JsonObject jsonObject) {
+		Mark mark;
+		
+		String type = jsonObject.getString("type");
+		if(type.contains("Collection") || type.contains("Chart")) { // COLLECTIONS
+			mark = new LineConnectedCollection(parent, true);
+			
+			double thickness = jsonObject.getJsonNumber("thickness").doubleValue();
+			mark.border.set(thickness);				
+			String stroke = jsonObject.getString("stroke");
+			mark.strokePaint.set(Paint.valueOf(stroke));
+			double rotation = jsonObject.getJsonNumber("rotation").doubleValue();
+			mark.angle.set(rotation);
+			
+			ReferenceCoords refCoords = new ReferenceCoords(RefX.Left, RefY.Bottom);
+			mark.setRefCoords(refCoords);
+			
+			double x = jsonObject.getJsonNumber("x").doubleValue();
+			double y = jsonObject.getJsonNumber("y").doubleValue();
+			PositionCoords coords = new PositionCoords(mark, x, y);
+			coords.xRef.set(RefX.Left);
+			coords.yRef.set(RefY.Bottom);
+			mark.coords = coords;
+			
+			mark.setLevel(jsonObject.getJsonNumber("level").intValue());
+			
+			String stickX = jsonObject.getString("sticky-x");
+			((VisBody)mark).alignYProperty.set(XSticky.valueOf(stickX));
+			String stickY = jsonObject.getString("sticky-y");
+			((VisBody)mark).alignXProperty.set(YSticky.valueOf(stickY));
+			
+			String distrX = jsonObject.getString("distribution-x");
+			((VisBody)mark).constraintXProperty.set(Constraint.valueOf(distrX));
+			String distrY = jsonObject.getString("distribution-y");
+			((VisBody)mark).constraintYProperty.set(Constraint.valueOf(distrY));
+			
+			double deltaX = jsonObject.getJsonNumber("delta-x").doubleValue();
+			((VisBody)mark).distanceXProperty.set(deltaX);
+			if(((VisBody)mark).constraintXProperty.get() == Constraint.None) 
+				((VisBody)mark).distanceXProperty.getActiveProperty().set(false);
+			
+			double deltaY = jsonObject.getJsonNumber("delta-y").doubleValue();
+			((VisBody)mark).distanceYProperty.set(deltaY);
+			if(((VisBody)mark).constraintYProperty.get() == Constraint.None) 
+				((VisBody)mark).distanceYProperty.getActiveProperty().set(false);
+			
+			String curve = jsonObject.getString("curve");
+			((LineConnectedCollection)mark).lineProperty = new LineTypeProperty(mark, LineTypeProperty.Type.valueOf(curve));
+		
+			JsonArray componentsArray = jsonObject.getJsonArray("components");
+			Collection<Mark> children = readChildrenFromJasonArray(mark, componentsArray);
+			for(Mark child: children) {
+				((VisBody)mark).attachCopy(child);
+			}
+			
+			JsonArray commonArray = jsonObject.getJsonArray("common");
+			JsonArray variableArray = jsonObject.getJsonArray("variable");
+						
+			///// Construct the property structure
+			((VisCollection)mark).setPropertyStructure(new CollectionPropertyStructure(children, 
+					readPropertyNames(commonArray), readPropertyNames(variableArray)));
+			
+			//// CONNECTIONS
+			JsonArray connectionsArray = jsonObject.getJsonArray("connections");
+			if(connectionsArray != null) {
+				String fill = jsonObject.getString("fill");
+				((LineConnectedCollection)mark).flowPaint.set(Paint.valueOf(fill));
+				
+				double opacity = jsonObject.getJsonNumber("opacity").doubleValue();
+				((LineConnectedCollection)mark).flowOpacity.set(opacity);
+				
+				String coloringScheme = jsonObject.getString("coloring");
+				((LineConnectedCollection)mark).coloringScheme.set(ColoringSchemeProperty.Scheme.valueOf(coloringScheme));
+				
+				if(((LineConnectedCollection)mark).coloringScheme.get() != Scheme.Common) 
+					((LineConnectedCollection)mark).flowPaint.getActiveProperty().set(false);
+				
+				FlowConnections connections = readConnections(connectionsArray, (LineConnectedCollection)mark);
+				((LineConnectedCollection)mark).setFlowConnections(connections);
+			}
+			
+			mark.initProperties();
+			
+		} else if(type.contains("Group")) {  // GROUPS
+			mark = new VisGroup(parent, true);
+			
+			double rotation = jsonObject.getJsonNumber("rotation").doubleValue();
+			mark.angle.set(rotation);
+			
+			ReferenceCoords refCoords = new ReferenceCoords(RefX.Left, RefY.Bottom);
+			mark.setRefCoords(refCoords);
+			
+			double x = jsonObject.getJsonNumber("x").doubleValue();
+			double y = jsonObject.getJsonNumber("y").doubleValue();
+			PositionCoords coords = new PositionCoords(mark, x, y);
+			coords.xRef.set(RefX.Left);
+			coords.yRef.set(RefY.Bottom);
+			mark.coords = coords;
+			
+			mark.setLevel(jsonObject.getJsonNumber("level").intValue());
+			
+			String stickX = jsonObject.getString("sticky-x");
+			((VisBody)mark).alignYProperty.set(XSticky.valueOf(stickX));
+			String stickY = jsonObject.getString("sticky-y");
+			((VisBody)mark).alignXProperty.set(YSticky.valueOf(stickY));
+			
+			String distrX = jsonObject.getString("distribution-x");
+			((VisBody)mark).constraintXProperty.set(Constraint.valueOf(distrX));
+			String distrY = jsonObject.getString("distribution-y");
+			((VisBody)mark).constraintYProperty.set(Constraint.valueOf(distrY));
+			
+			double deltaX = jsonObject.getJsonNumber("delta-x").doubleValue();
+			((VisBody)mark).distanceXProperty.set(deltaX);
+			if(((VisBody)mark).constraintXProperty.get() == Constraint.None) 
+				((VisBody)mark).distanceXProperty.getActiveProperty().set(false);
+			
+			double deltaY = jsonObject.getJsonNumber("delta-y").doubleValue();
+			((VisBody)mark).distanceYProperty.set(deltaY);
+			if(((VisBody)mark).constraintYProperty.get() == Constraint.None) 
+				((VisBody)mark).distanceYProperty.getActiveProperty().set(false);
+			
+			///////////////
+			JsonArray componentsArray = jsonObject.getJsonArray("components");
+			Collection<Mark> children = readChildrenFromJasonArray(mark, componentsArray);
+			for(Mark child: children) {
+				((VisBody)mark).attachCopy(child);
+			}
+			
+			JsonArray commonArray = jsonObject.getJsonArray("common");
+			JsonArray variableArray = jsonObject.getJsonArray("variable");
+						
+			///// Construct the property structure
+			((VisGroup)mark).setPropertyStructure(new GroupPropertyStructure(children, 
+					readPropertyNames(commonArray), readPropertyNames(variableArray)));
+			
+			// Create and add bindings
+			JsonArray bindingsArray = jsonObject.getJsonArray("bindings");
+			if(bindingsArray != null) {
+				TreeMap<PropertyName, ArrayList<GroupBinding>> bindings = readBindings(bindingsArray, (VisGroup)mark);
+				((VisGroup)mark).getChildPropertyStructure().setBindings(bindings);
+			}
+			
+			mark.initProperties();
+			
+			JsonArray publicArray = jsonObject.getJsonArray("public");
+			if(publicArray != null) {
+				SortedSet<PropertyName> publicProperties = readPropertyNames(publicArray);
+				for(Property property : ((VisGroup)mark).getAllProperties()) {	//System.err.println(property.getName());		
+					if(publicProperties.contains(new PropertyName(property.getName()))) 
+						((Shareable)property).getPublicProperty().set(true);
+					else ((Shareable)property).getPublicProperty().set(false);
+				}
+			}
+			
+		} else { // Shape Mark	
+			ShapeProperty.Type shapeType;
+			
+			if(type.equals("Text")) {
+				shapeType = Type.Text;
+			} else {
+				String shape = jsonObject.getString("shape");
+				if(shape.equals("Rectangle")) shapeType = Type.Rectangle;
+				else if(shape.equals("Ellipse")) shapeType = Type.Ellipse;
+				else if(shape.equals("Triangle")) shapeType = Type.Triangle;
+				else shapeType = Type.Line;
+			}
+			
+			double width = jsonObject.getJsonNumber("width").doubleValue();
+			double height = jsonObject.getJsonNumber("height").doubleValue();
+			mark = ShapeMark.createInstance(parent, true, shapeType, width, height);
+			
+			((ShapeMark)mark).shapeProperty.set(shapeType);
+			
+			boolean lock = jsonObject.getString("lock").equals("true");
+			mark.ratiolock.set(lock);
+			
+			double x = jsonObject.getJsonNumber("x").doubleValue();
+			double y = jsonObject.getJsonNumber("y").doubleValue();
+			PositionCoords coords = new PositionCoords(mark, x, y);
+			RefX referencex = ReferenceCoords.getXRef(jsonObject.getString("reference-x"));
+			RefY referencey = ReferenceCoords.getYRef(jsonObject.getString("reference-y"));
+			coords.xRef.set(referencex);
+			coords.yRef.set(referencey);
+			mark.coords = coords;
+			
+			double rotation = jsonObject.getJsonNumber("rotation").doubleValue();
+			mark.angle.set(rotation);
+			
+			String fill = jsonObject.getString("fill");
+			mark.paint.set(Paint.valueOf(fill));
+			
+			if(shapeType == Type.Text) {
+				String text = jsonObject.getString("text");
+				((TextualMark)mark).textProperty.set(text);
+				double fontsize = jsonObject.getJsonNumber("fontsize").doubleValue();
+				((TextualMark)mark).fontSize.set(fontsize);
+			} else {
+				double thickness = jsonObject.getJsonNumber("thickness").doubleValue();
+				mark.border.set(thickness);				
+				String stroke = jsonObject.getString("stroke");
+				mark.strokePaint.set(Paint.valueOf(stroke));
+			}
+			
+			mark.initProperties();
+		}
+		
+		/////////
+		mark.update();
+		
+		// TODO Auto-generated method stub
+		return mark;
+	}
+	
+	
+	private static SortedSet<PropertyName> readPropertyNames(JsonArray jsonArray){
+		TreeSet<PropertyName> propertyNames = new TreeSet<>();
+		
+		for(int i = 0; i < jsonArray.size(); ++i) {
+			PropertyName name = new PropertyName(jsonArray.getJsonString(i).getString());
+			propertyNames.add(name);
+		}
+		
+		return propertyNames;
+	}
+	
+	private static FlowConnections readConnections(JsonArray jsonArray, LineConnectedCollection collection) {
+		FlowConnections connections = new FlowConnections(collection);
+		for(int i = 0; i < jsonArray.size(); ++i) {
+			JsonObject connObject = jsonArray.getJsonObject(i);
+			
+			String colId = collection.id.get();
+			String originId = colId +"." + connObject.getString("origin");
+			String destinationId = colId +"." + connObject.getString("destination");
+						
+			double weight = connObject.getJsonNumber("weight").doubleValue();
+			
+			FlowConnection connection = new FlowConnection(collection, 
+					(ShapeMark)collection.getNodeWithId(originId), (ShapeMark)collection.getNodeWithId(destinationId));
+			connection.weight.set(weight);
+			connections.add(connection);
+		}
+		
+		return connections;
+	}
+	
+	private static TreeMap<PropertyName, ArrayList<GroupBinding>> readBindings(JsonArray jsonArray, VisGroup group) {
+		TreeMap<PropertyName, ArrayList<GroupBinding>> bindings = new TreeMap<>();
+		
+		Map<PropertyName, FlexibleListProperty> properties = group.getChildPropertyStructure().getProperties();
+		
+		for(int i = 0; i < jsonArray.size(); ++i) {
+			JsonArray bindingArray = jsonArray.getJsonArray(i);
+			ArrayList<Property> boundProps = new ArrayList<>();
+			
+			FlexibleListProperty propList = null;
+			for(int k = 0; k < bindingArray.size(); ++k) {
+				PropertyName name = new PropertyName(bindingArray.getString(k));
+				if(propList == null) propList = properties.get(name);
+				Property property = propList.getByName(name);
+				if(property!=null) boundProps.add(property);
+			}
+			
+			PropertyName name = new PropertyName(new PropertyName(boundProps.get(0).getName()).getNoPostfixName());
+			ArrayList<GroupBinding> binding = bindings.get(name);
+			if(binding == null) {
+				binding = new ArrayList<>();
+				bindings.put(name, binding);
+			}
+			binding.add(new GroupBinding(boundProps));			
+		}
+	
+		return bindings;
+	}
+}
+
diff --git a/src/fr/inria/structgraphics/persistence/JsonObjectWriter.java b/src/fr/inria/structgraphics/persistence/JsonObjectWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..2114efa9873ce278268e289fa41e8a3551ca84a1
--- /dev/null
+++ b/src/fr/inria/structgraphics/persistence/JsonObjectWriter.java
@@ -0,0 +1,255 @@
+package fr.inria.structgraphics.persistence;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.SortedSet;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import javax.json.JsonValue.ValueType;
+
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.Shareable;
+import fr.inria.structgraphics.ui.utils.GroupBinding;
+import fr.inria.structgraphics.ui.viscanvas.groupings.CollectionPropertyStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnection;
+import fr.inria.structgraphics.ui.viscanvas.groupings.GroupPropertyStructure;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleDoubleProperty;
+
+public class JsonObjectWriter {
+	
+	public static JsonObject saveToJason(Collection<Mark> marks, boolean isLibrary) {		
+		return buildJason(marks, isLibrary).build();
+	}
+	
+	public static JsonObjectBuilder buildJason(Collection<Mark> marks, boolean isLibrary, JsonObjectBuilder visbuilder) {
+		JsonArrayBuilder builder = Json.createArrayBuilder();
+		for(Mark mark: marks) {
+			save(builder, mark, mark);
+		}
+		
+		visbuilder.add(isLibrary? "library" : "visualizations", builder);
+		
+		return visbuilder;
+	}
+	
+	public static JsonObjectBuilder buildJason(Collection<Mark> marks, boolean isLibrary) {
+		JsonObjectBuilder visbuilder = Json.createObjectBuilder();
+		return buildJason(marks, isLibrary, visbuilder);		
+	}
+	
+	private static JsonArrayBuilder save(JsonArrayBuilder parentBuilder, Mark mark, Mark root) {
+		JsonObjectBuilder builder = Json.createObjectBuilder();
+		builder.add("type", mark.getType());	
+		if(mark != root) { // Since the ID of the root node may change when re-loaded to the canvas
+			builder.add("id", getRelativeId(root.id.get(), mark.id.get()));
+		}
+		builder.add("level", mark.getLevel());
+		
+		if(mark instanceof VisBody) {
+			builder.add("prefix", PropertyName.getPrefix(mark.getLevel()));
+		}
+		
+		List<Property> properties = mark.getProperties();
+		for(Property prop: properties) saveProperty(builder, prop);
+		
+		if(mark instanceof VisCollection) {
+			// Save the property structure
+			CollectionPropertyStructure structure = ((VisCollection)mark).getChildPropertyStructure();
+			SortedSet<PropertyName> common = structure.getCommon();
+			JsonArrayBuilder commonBuilder = Json.createArrayBuilder();
+			for(PropertyName name: common) commonBuilder.add(name.toString());
+			builder.add("common", commonBuilder.build());
+			
+			SortedSet<PropertyName> variable = structure.getVariable();		
+			JsonArrayBuilder variableBuilder = Json.createArrayBuilder();
+			for(PropertyName name: variable) variableBuilder.add(name.toString());
+			builder.add("variable", variableBuilder.build());	
+		} else if(mark instanceof VisGroup) {
+			////////////
+			GroupPropertyStructure structure = ((VisGroup)mark).getChildPropertyStructure();
+			SortedSet<PropertyName> common = structure.getCommon();
+			JsonArrayBuilder commonBuilder = Json.createArrayBuilder();
+			for(PropertyName name: common) commonBuilder.add(name.toString());
+			builder.add("common", commonBuilder.build());
+			
+			SortedSet<PropertyName> variable = structure.getVariable();		
+			JsonArrayBuilder variableBuilder = Json.createArrayBuilder();
+			for(PropertyName name: variable) variableBuilder.add(name.toString());
+			builder.add("variable", variableBuilder.build());	
+			
+			if(((VisGroup)mark).isTopGroup()) {
+				JsonArrayBuilder publicBuilder = Json.createArrayBuilder();
+				for(Property prop: ((VisGroup)mark).getAllProperties()) {
+					if(prop instanceof Shareable && ((Shareable)prop).getPublicProperty().get())
+						publicBuilder.add(prop.getName());
+				}
+				builder.add("public", publicBuilder.build());
+					
+				JsonArrayBuilder bindingsBuilder = Json.createArrayBuilder();
+								
+				for(PropertyName propName: structure.getProperties().keySet()) {
+					
+					ArrayList<GroupBinding> bindings = structure.getGroups(propName);
+					if(bindings == null) continue;
+					for(GroupBinding binding: bindings) {
+						JsonArrayBuilder propBuilder = Json.createArrayBuilder();
+						
+						ArrayList boundproperties = binding.getProperties();
+						for(int i = 0; i < boundproperties.size(); ++i) {
+							propBuilder.add(((Property)boundproperties.get(i)).getName());
+						}
+						
+						bindingsBuilder.add(propBuilder);
+					}
+				}
+				
+				builder.add("bindings", bindingsBuilder.build()); 
+			}
+		} else saveProperty(builder, mark.ratiolock);
+		
+		List<Mark> components = mark.getComponents();
+		if(!components.isEmpty()) {
+			JsonArrayBuilder childrenBuilder = Json.createArrayBuilder();			
+			for(Mark child: components) {
+				save(childrenBuilder, child, root);
+			}
+			
+			builder.add("components", childrenBuilder);
+		}
+		
+		
+		if(mark instanceof LineConnectedCollection && ((LineConnectedCollection)mark).hasConnections()) {
+			LineConnectedCollection collection = ((LineConnectedCollection)mark);
+			builder.add(new PropertyName(collection.flowPaint.getName()).getCleanName(), collection.flowPaint.get().toString());
+			builder.add(new PropertyName(collection.flowOpacity.getName()).getCleanName(), collection.flowOpacity.get());
+			builder.add(new PropertyName(collection.coloringScheme.getName()).getCleanName(), collection.coloringScheme.get().toString());
+			
+			JsonArrayBuilder connectionsArrayBuilder = Json.createArrayBuilder();
+			// Save the flow connections structure
+			for(FlowConnection conn : collection.getFlowConnections()) {
+				JsonObjectBuilder connectionBuilder = Json.createObjectBuilder();
+				connectionBuilder.add("origin", getRelativeId(root.id.get(), conn.getOrigin().id.get()));
+				connectionBuilder.add("destination", getRelativeId(root.id.get(), conn.getDestination().id.get()));
+				connectionBuilder.add("weight", conn.weight.get());
+				
+				connectionsArrayBuilder.add(connectionBuilder);
+			}
+			
+			builder.add("connections", connectionsArrayBuilder);
+		}
+		
+		parentBuilder.add(builder);
+		return parentBuilder;
+	}
+	
+	private static void saveProperty(JsonObjectBuilder builder, Property property) {
+		PropertyName propName = new PropertyName(property.getName());
+		
+		if(property instanceof SimpleDoubleProperty)
+			builder.add(propName.getCleanName(), ((SimpleDoubleProperty)property).doubleValue());
+		else builder.add(propName.getCleanName(), property.getValue().toString());
+	}
+	
+
+	public static StringBuffer fromArrayToReadableString(JsonArray array, int level) {
+		StringBuffer buffer = new StringBuffer();
+		if(array.isEmpty()) {
+			buffer.append("[]");
+			return buffer;
+		}
+
+		if(array.get(0).getValueType() == ValueType.STRING) {
+			buffer.append("[");
+	        for(int i = 0; i < array.size(); ++i) {
+	        	JsonString value = array.getJsonString(i);
+	        	buffer.append(value);
+	        	buffer.append(",");
+	        }
+	        buffer.deleteCharAt(buffer.length() - 1);
+			buffer.append("]");
+		} 
+		else if(array.get(0).getValueType() == ValueType.ARRAY) {
+			buffer.append("[\n");
+			
+	        for(int i = 0; i < array.size(); ++i) {
+	        	JsonArray visObject = array.getJsonArray(i);
+				buffer.append(tabs(level+1));
+	        	buffer.append(fromArrayToReadableString(visObject, (level + 1)));
+	        	buffer.append(",\n");
+	        }
+
+			buffer.deleteCharAt(buffer.length() - 2);
+			buffer.append(tabs(level) + "]");
+		}
+		else {
+			buffer.append("[\n");
+			
+	        for(int i = 0; i < array.size(); ++i) {
+	        	JsonObject visObject = array.getJsonObject(i);
+	        	buffer.append(fromObjectToReadableString(visObject, (level + 1)));
+	        	buffer.append(",\n");
+	        }
+
+			buffer.deleteCharAt(buffer.length() - 2);
+			buffer.append(tabs(level) + "]");
+		}
+
+		
+		return buffer;
+	}
+	
+	private static String getRelativeId(String rootId, String id) {
+		return id.substring(rootId.length() + 1);
+	}
+	
+	public static StringBuffer fromObjectToReadableString(JsonObject visObject, int level) {
+		StringBuffer buffer = new StringBuffer();
+		
+		buffer.append(tabs(level) + "{\n");	
+		
+		for(Entry<String, JsonValue> entry: visObject.entrySet()) {
+			buffer.append(tabs(level + 1));
+			buffer.append("\"" + entry.getKey() + "\"");
+			buffer.append(":");
+			
+			JsonValue value = entry.getValue();
+			if(value instanceof JsonArray) {
+				buffer.append(fromArrayToReadableString((JsonArray)value, (level + 2)));
+			} else if(value instanceof JsonObject) {
+				buffer.append(fromObjectToReadableString((JsonObject)value, (level + 2)));
+			}
+			else buffer.append(entry.getValue());
+			
+			buffer.append(",\n");
+		}
+		
+		buffer.deleteCharAt(buffer.length() - 2);
+		
+		buffer.append(tabs(level) + "}");
+
+		return buffer;
+	}
+	
+	private static StringBuffer tabs(int num) {
+		StringBuffer str = new StringBuffer();
+		for(int i = 0; i < num; ++i) str.append("  ");
+		
+		return str;
+	}
+
+}
+
diff --git a/src/fr/inria/structgraphics/persistence/JsonSpreadsheetWriterReader.java b/src/fr/inria/structgraphics/persistence/JsonSpreadsheetWriterReader.java
new file mode 100644
index 0000000000000000000000000000000000000000..6d737a61ea1018b61f3af0ffe6e909587c4ad133
--- /dev/null
+++ b/src/fr/inria/structgraphics/persistence/JsonSpreadsheetWriterReader.java
@@ -0,0 +1,211 @@
+package fr.inria.structgraphics.persistence;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeMap;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.PositionCoords;
+import fr.inria.structgraphics.graphics.ReferenceCoords;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.Draggable;
+import fr.inria.structgraphics.ui.Draggable.Type;
+import fr.inria.structgraphics.ui.spreadsheet.AreaContent;
+import fr.inria.structgraphics.ui.spreadsheet.AreaSourceInfo;
+import fr.inria.structgraphics.ui.spreadsheet.ColumnVariable;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import fr.inria.structgraphics.ui.spreadsheet.DiscreteTransformation;
+import fr.inria.structgraphics.ui.spreadsheet.MappingProperty;
+import fr.inria.structgraphics.ui.spreadsheet.MathTransformation;
+import fr.inria.structgraphics.ui.spreadsheet.Spreadsheet;
+import fr.inria.structgraphics.ui.spreadsheet.SpreadsheetArea;
+import fr.inria.structgraphics.ui.spreadsheet.VectorVariable;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable.DataType;
+import javafx.beans.property.StringProperty;
+import javafx.scene.paint.Paint;
+
+public class JsonSpreadsheetWriterReader {
+	
+	public static JsonObjectBuilder buildJason(Spreadsheet sheet, JsonObjectBuilder visbuilder) {
+		List<SpreadsheetArea> areas = sheet.getAreas();		
+		JsonArrayBuilder builder = Json.createArrayBuilder();
+		for(SpreadsheetArea area: areas) {
+			save(builder, area);
+		}
+		
+		visbuilder.add("datasheet", builder);
+		
+		return visbuilder;
+	}
+	
+	public static JsonObjectBuilder buildJason(Spreadsheet sheet) {
+		JsonObjectBuilder visbuilder = Json.createObjectBuilder();
+		return buildJason(sheet, visbuilder);		
+	}
+
+	private static JsonArrayBuilder save(JsonArrayBuilder parentBuilder, SpreadsheetArea area) {
+		JsonObjectBuilder builder = Json.createObjectBuilder();
+		
+		builder.add("type", area.getType().toString());
+		
+		builder.add("row", area.getStartRow());
+		builder.add("column", area.getStartColumn());
+		builder.add("nrows", area.nrows());
+		builder.add("ncolumns", area.ncolumns());
+	
+		builder.add("source", area.getSource().id.get());
+		if(area.getVisBody() != null) builder.add("group", area.getVisBody().id.get());
+		builder.add("wide", area.isWide());
+		builder.add("network", area.isNetwork());
+		
+		ArrayList<PropertyName> names = area.getPropertyNames();
+		JsonArrayBuilder namesArray = Json.createArrayBuilder();
+		for(PropertyName name: names) {
+			namesArray.add(name.toString());
+		}
+		builder.add("properties", namesArray);
+		
+		JsonArrayBuilder variablesArray = Json.createArrayBuilder();
+		// TODO: To add the variable mappings
+		AreaContent areaContent = area.getAreaContent();
+		for(DataVariable variable : areaContent.getVariables()) {
+			JsonObjectBuilder varObject = Json.createObjectBuilder();	
+			
+			varObject.add("name", variable.getPropertyName());
+			varObject.add("type", variable.getType().toString());
+			
+			// Labels, axes, legends
+			varObject.add("axis", variable.scaleShownProperty.get());
+			varObject.add("axis-outer", variable.scaleShownPropertyOuter.get());
+			varObject.add("legend", variable.legendShownProperty.get());
+			varObject.add("node", variable.nodeShownProperty.get());
+			
+			JsonArrayBuilder labelsArray = Json.createArrayBuilder();
+			for(String label: variable.getNames()) {
+				labelsArray.add(label);
+			}
+			varObject.add("labels", labelsArray);
+
+			/// Add the transformation
+			if(variable.getType() == DataType.Functional) {
+				varObject.add("function", variable.transformationProperty().get().getExpression().getValue());
+			} else {
+				DiscreteTransformation transform = (DiscreteTransformation) variable.transformationProperty().get();
+				TreeMap<MappingProperty, StringProperty> map = transform.getMap();
+				JsonArrayBuilder mappingsArray = Json.createArrayBuilder();
+				
+				for(MappingProperty prop: map.keySet()) {
+					JsonObjectBuilder mappingObject = Json.createObjectBuilder();
+					StringProperty val = map.get(prop);
+					mappingObject.add("from", prop.getValue().toString());
+					mappingObject.add("to", val.get());
+					mappingsArray.add(mappingObject);
+				}
+				
+				varObject.add("mappings", mappingsArray);
+			}
+			///
+			variablesArray.add(varObject );
+		}
+		builder.add("variables", variablesArray);
+		
+		parentBuilder.add(builder);
+		return parentBuilder;
+	}
+	
+
+	public static void readSpreadsheetFromJasonObject(JsonArray jsonArray, VisFrame visFrame, Spreadsheet sheet) {		
+		for(int i = 0; i < jsonArray.size(); ++i) {
+			JsonValue jsonObject = jsonArray.get(i);
+			
+			if(jsonObject instanceof JsonObject) {
+				readAreaFromJasonObject((JsonObject)jsonObject, visFrame, sheet);
+			}
+		}
+	}
+	
+	private static void readAreaFromJasonObject(JsonObject jsonObject, VisFrame visFrame, Spreadsheet sheet) {
+		Type type = Draggable.Type.valueOf(jsonObject.getString("type"));
+		int row = jsonObject.getInt("row");
+		int column = jsonObject.getInt("column");
+		int nrows = jsonObject.getInt("nrows");
+		int ncolumns = jsonObject.getInt("ncolumns");
+		
+		boolean isWide = jsonObject.getBoolean("wide");
+		boolean isNetwork = jsonObject.getBoolean("network");
+		
+		Container source = visFrame.getComponent(jsonObject.getString("source"));
+		JsonString groupID = jsonObject.getJsonString("group");
+		VisBody visBody = (groupID == null) ? null : (VisBody)visFrame.getComponent(groupID.toString());
+	
+		JsonArray propertiesArray = jsonObject.getJsonArray("properties");
+		ArrayList<PropertyName> propertyNames = new ArrayList<>();
+		for(int i = 0; i < propertiesArray.size(); ++i) {
+			PropertyName name = new PropertyName(propertiesArray.getJsonString(i).getString());
+			propertyNames.add(name);
+		}
+		
+		AreaSourceInfo info = new AreaSourceInfo(source, visBody, propertyNames, type, isWide, isNetwork);
+		SpreadsheetArea area = new SpreadsheetArea(sheet, row, column, ncolumns, nrows);
+		area.setInfo(info);
+		sheet.addArea(area);
+		
+		AreaContent content = area.getAreaContent();
+		
+		/// Variables
+		JsonArray variablesArray = jsonObject.getJsonArray("variables");
+		for(int i = 0; i < variablesArray.size(); ++i) {
+			JsonObject varObject = variablesArray.getJsonObject(i);
+			
+			String varName = varObject.getString("name");
+			DataVariable variable = content.getVariable(varName);
+			
+			DataType datatype = DataType.valueOf(varObject.getString("type"));
+			JsonArray labelsArray = varObject.getJsonArray("labels");
+			for(int k = 0; k < labelsArray.size(); ++k) {
+				String label = labelsArray.getString(k);
+				variable.getName(k).set(label);
+			}
+						
+			if(datatype == DataType.Functional) {
+				String expression = varObject.getString("function");
+				MathTransformation mathTransform = new MathTransformation(variable);
+				mathTransform.setExpression(expression);
+				variable.transformationProperty().set(mathTransform);
+			} else {
+				DiscreteTransformation discreteTransform = new DiscreteTransformation(variable);
+				variable.transformationProperty().set(discreteTransform);
+				
+				JsonArray mappingsArray = varObject.getJsonArray("mappings");
+				for(int k = 0; k < mappingsArray.size(); ++k) {				
+					JsonObject mapping = mappingsArray.getJsonObject(k);
+					discreteTransform.replace(mapping.getString("from"), mapping.getString("to"));					
+				}
+			}
+			
+			// Labels, axes, legends
+			if(varObject.getBoolean("axis")) sheet.showOnGraph(variable);
+			if(varObject.getBoolean("axis-outer")) sheet.showOnParentGraph(variable);
+			if(varObject.getBoolean("legend")) sheet.showOnLegend(variable);
+			if(varObject.getBoolean("node")) sheet.showOnNode(variable);			
+		}
+		
+	}
+}
+
+
+
diff --git a/src/fr/inria/structgraphics/persistence/JsonWorkspaceWriter.java b/src/fr/inria/structgraphics/persistence/JsonWorkspaceWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..d471bf4f4a9dfa9be31e5b7aaa04b4c53381fb97
--- /dev/null
+++ b/src/fr/inria/structgraphics/persistence/JsonWorkspaceWriter.java
@@ -0,0 +1,27 @@
+package fr.inria.structgraphics.persistence;
+
+import java.util.Collection;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.ui.spreadsheet.Spreadsheet;
+
+public class JsonWorkspaceWriter {
+	
+	public static JsonObject saveToJason(Collection<Mark> librarymarks, Collection<Mark> canvasmarks, Spreadsheet sheet) {	
+		JsonObjectBuilder rootBuilder = Json.createObjectBuilder();
+		
+		JsonObjectBuilder spaceBuilder = JsonObjectWriter.buildJason(librarymarks, true); 
+		JsonObjectWriter.buildJason(canvasmarks, false, spaceBuilder); 
+		JsonSpreadsheetWriterReader.buildJason(sheet, spaceBuilder);
+		
+		rootBuilder.add("workspace", spaceBuilder);
+		
+		return rootBuilder.build();
+	}
+
+}
+
diff --git a/src/fr/inria/structgraphics/types/AlignmentProperty.java b/src/fr/inria/structgraphics/types/AlignmentProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..159cb643597f85c4e44ea87429ebe68d0d461eaf
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/AlignmentProperty.java
@@ -0,0 +1,60 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+
+public class AlignmentProperty<T> extends SimpleObjectProperty<T> implements Shareable {
+		
+	public enum YSticky {
+		No, Yes 
+	}
+	
+	public enum XSticky {
+		No, Yes
+	}
+	
+	public AlignmentProperty(Object bean, String name, T value) {
+		super(bean, name, value);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+
+	protected BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof AlignmentProperty) {
+			return getValue().equals(((AlignmentProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/AlignmentXProperty.java b/src/fr/inria/structgraphics/types/AlignmentXProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..664b6a0b6130ce2f18e374059b878bf377c3a4a2
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/AlignmentXProperty.java
@@ -0,0 +1,24 @@
+package fr.inria.structgraphics.types;
+
+public class AlignmentXProperty extends AlignmentProperty<AlignmentProperty.YSticky> {
+
+	public AlignmentXProperty(Object bean) {
+		super(bean, "sticky-y", YSticky.No);
+	}
+	
+	public AlignmentXProperty(Object bean, YSticky value) {
+		super(bean, "sticky-y", value);
+	}
+	
+	/*
+	public String getIconName() {
+		return "x-" + getValue().toString().toLowerCase();
+	}*/
+	
+	@Override 
+	public void setValue(AlignmentProperty.YSticky value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/types/AlignmentYProperty.java b/src/fr/inria/structgraphics/types/AlignmentYProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..81adb061ce726665932434ae3eab56b319fcf932
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/AlignmentYProperty.java
@@ -0,0 +1,28 @@
+package fr.inria.structgraphics.types;
+
+import javafx.beans.property.Property;
+
+public class AlignmentYProperty extends AlignmentProperty<AlignmentProperty.XSticky> {
+
+	static int counter = 0;
+	
+	public AlignmentYProperty(Object bean) {
+		super(bean, "sticky-x", XSticky.No);
+	}
+	
+	public AlignmentYProperty(Object bean, XSticky value) {
+		super(bean, "sticky-x", value);
+	}
+	
+	/*
+	public String getIconName() {
+		return "y-" + getValue().toString().toLowerCase();
+	}*/
+	
+	@Override 
+	public void setValue(AlignmentProperty.XSticky value) {		
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/AngleProperty.java b/src/fr/inria/structgraphics/types/AngleProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7041476aa5241830e9778da8a1fb9615f7878c3
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/AngleProperty.java
@@ -0,0 +1,60 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+
+public class AngleProperty extends SimpleDoubleProperty implements Shareable {
+
+	protected final static double EPSILON = 5;
+	
+	public AngleProperty(Object bean, String name, double val) {
+		super(bean, name, val);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(Number value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof AngleProperty) {
+			if(Math.abs(((AngleProperty) property).get() - get()) < EPSILON) return true;
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/CardinalityProperty.java b/src/fr/inria/structgraphics/types/CardinalityProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..ceef14cf24027874f285140948bca9889dc48af0
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/CardinalityProperty.java
@@ -0,0 +1,59 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+
+public class CardinalityProperty extends SimpleIntegerProperty implements Shareable{
+	
+
+	public CardinalityProperty(Object bean) {
+		super(bean, "cardinality");
+	}
+	
+	public CardinalityProperty(Object bean, String name, int value) {
+		super(bean, name, value);
+	}
+
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof CardinalityProperty) {
+			return getValue().equals(((CardinalityProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/ColorListProperty.java b/src/fr/inria/structgraphics/types/ColorListProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..e0515f3cf84c5094853f7e78cfb3a6728116053b
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ColorListProperty.java
@@ -0,0 +1,13 @@
+package fr.inria.structgraphics.types;
+
+import java.util.ArrayList;
+import javafx.collections.FXCollections;
+
+public class ColorListProperty extends FlexibleListProperty{
+
+	public ColorListProperty(Object bean, ColorProperty property) {
+		super(bean, property.getName(), FXCollections.observableArrayList(new ArrayList<ColorProperty>()));
+		add(property);
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/ColorProperty.java b/src/fr/inria/structgraphics/types/ColorProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9a655393c07013c4bf11d0596be7226f2c51240
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ColorProperty.java
@@ -0,0 +1,59 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.scene.paint.Paint;
+
+public class ColorProperty extends SimpleObjectProperty<Paint> implements Shareable {
+	public ColorProperty(java.lang.Object bean, String name, Paint color) {
+		super(bean, name, color);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) {
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(Paint value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof ColorProperty) {
+			return getValue().equals(((ColorProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/ColoringSchemeProperty.java b/src/fr/inria/structgraphics/types/ColoringSchemeProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..c66dd469cd7397ae51812213cf51fba0768cbfd4
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ColoringSchemeProperty.java
@@ -0,0 +1,62 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+
+public class ColoringSchemeProperty extends SimpleObjectProperty<ColoringSchemeProperty.Scheme> implements Shareable {
+
+	public enum Scheme {
+		Common, Source, Destination 
+	}
+	
+	public ColoringSchemeProperty(Object bean, ColoringSchemeProperty.Scheme value) {
+		super(bean, "coloring", value);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(ColoringSchemeProperty.Scheme value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof ColoringSchemeProperty) {
+			return getValue().equals(((ColoringSchemeProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/ComponentRefProperty.java b/src/fr/inria/structgraphics/types/ComponentRefProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f3560add5e2e3a0ae668c40aa55333d004a769d
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ComponentRefProperty.java
@@ -0,0 +1,11 @@
+package fr.inria.structgraphics.types;
+
+
+public class ComponentRefProperty<T> extends RefProperty<T> {
+
+	public ComponentRefProperty(Object bean, String name, T value) {
+		super(bean, name, value);
+	}
+	
+}
+
diff --git a/src/fr/inria/structgraphics/types/ComponentRefXProperty.java b/src/fr/inria/structgraphics/types/ComponentRefXProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..0125d0f07fa7e8c777f51491c8f1ee21ea62541f
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ComponentRefXProperty.java
@@ -0,0 +1,21 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+
+public class ComponentRefXProperty extends ComponentRefProperty<RefX> {
+
+	public ComponentRefXProperty(Object bean) {
+		super(bean, "reference-x", RefX.Left);
+	}
+	
+	public ComponentRefXProperty(Object bean, RefX value) {
+		super(bean, "reference-x", value);
+	}
+	
+	
+	@Override 
+	public void setValue(RefX value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/ComponentRefYProperty.java b/src/fr/inria/structgraphics/types/ComponentRefYProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c079dd865e041070bdad2ff1ea962ad64275b48
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ComponentRefYProperty.java
@@ -0,0 +1,20 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+
+public class ComponentRefYProperty extends ComponentRefProperty<RefY> {
+
+	public ComponentRefYProperty(Object bean) {
+		super(bean, "reference-y", RefY.Bottom);
+	}
+	
+	public ComponentRefYProperty(Object bean, RefY value) {
+		super(bean, "reference-y", value);
+	}
+	
+	@Override 
+	public void setValue(RefY value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/ConnectionWeightProperty.java b/src/fr/inria/structgraphics/types/ConnectionWeightProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a3b19c335c9b59096851fec20433cac12d5cea9
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ConnectionWeightProperty.java
@@ -0,0 +1,13 @@
+package fr.inria.structgraphics.types;
+
+public class ConnectionWeightProperty extends DistanceProperty {
+
+	public ConnectionWeightProperty(java.lang.Object bean) {
+		super(bean, "weight", 0);		
+	}
+	
+	public ConnectionWeightProperty(java.lang.Object bean, double value) {
+		super(bean, "weight", value);		
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/ConstrainedDoubleProperty.java b/src/fr/inria/structgraphics/types/ConstrainedDoubleProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..40696b9eb202036b9be54448112dc43578fc2d73
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ConstrainedDoubleProperty.java
@@ -0,0 +1,80 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnection;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+
+public class ConstrainedDoubleProperty extends SimpleDoubleProperty implements Shareable {
+
+	protected final static double EPSILON = 5;
+	
+	public ConstrainedDoubleProperty(Object bean, String name, double val) {
+		super(bean, name, val);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(Number value) {
+		if(!value.equals(get())) super.setValue(value);
+		else {
+			fireValueChangedEvent();
+		}
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+	
+	public void updateValue(double value) {
+		this.setValue(value);
+	
+		if(getBean() instanceof Mark) {
+			Container container = ((Mark)getBean()).getContainer();
+			if(container instanceof VisBody) {
+				((VisBody)container).updateLayout((Mark)getBean());
+			}	
+		} else if(getBean() instanceof FlowConnection) {
+			Container container = ((FlowConnection)getBean()).getOrigin().getContainer();
+			if(container instanceof VisBody) {
+				((VisBody)container).updateLayout(((FlowConnection)getBean()).getOrigin());
+			}
+		}
+	}
+
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof ConstrainedDoubleProperty) {
+			if(Math.abs(((ConstrainedDoubleProperty) property).get() - get()) < EPSILON) return true;
+		}
+		
+		return false;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/types/ContainerRefProperty.java b/src/fr/inria/structgraphics/types/ContainerRefProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..aede7fde51745471217bb9d235e75ba4577f63c5
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ContainerRefProperty.java
@@ -0,0 +1,9 @@
+package fr.inria.structgraphics.types;
+
+public class ContainerRefProperty<T> extends RefProperty<T> {
+
+	public ContainerRefProperty(Object bean, String name, T value) {
+		super(bean, name, value);
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/types/ContainerRefXProperty.java b/src/fr/inria/structgraphics/types/ContainerRefXProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..02b3734b226718cc06da6896c06c4b2dbae98a57
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ContainerRefXProperty.java
@@ -0,0 +1,21 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+
+public class ContainerRefXProperty extends ContainerRefProperty<RefX> {
+
+	public ContainerRefXProperty(Object bean) {
+		super(bean, "reference-x", RefX.Left);
+	}
+	
+	public ContainerRefXProperty(Object bean, RefX value) {
+		super(bean, "reference-x", value);
+	}
+	
+	@Override 
+	public void setValue(RefX value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/ContainerRefYProperty.java b/src/fr/inria/structgraphics/types/ContainerRefYProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..83ad96ba52957073cf89a4406d3cdafb65808a31
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ContainerRefYProperty.java
@@ -0,0 +1,20 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+
+public class ContainerRefYProperty extends ContainerRefProperty<RefY> {
+
+	public ContainerRefYProperty(Object bean) {
+		super(bean, "reference-y", RefY.Bottom);
+	}
+	
+	public ContainerRefYProperty(Object bean, RefY value) {
+		super(bean, "reference-y", value);
+	}
+	
+	@Override 
+	public void setValue(RefY value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/CoordinateProperty.java b/src/fr/inria/structgraphics/types/CoordinateProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..723be49e900f0ec1b3b69f2f83a6292466db5293
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/CoordinateProperty.java
@@ -0,0 +1,8 @@
+package fr.inria.structgraphics.types;
+
+public class CoordinateProperty extends ConstrainedDoubleProperty {
+	
+	public CoordinateProperty(Object bean, String name, double val) {
+		super(bean, name, val);
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/DeltaXProperty.java b/src/fr/inria/structgraphics/types/DeltaXProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..79283016b47ce8f365f563a209578c9c3a537b02
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/DeltaXProperty.java
@@ -0,0 +1,13 @@
+package fr.inria.structgraphics.types;
+
+public class DeltaXProperty extends DistanceProperty {
+
+	public DeltaXProperty(java.lang.Object bean) {
+		super(bean, "delta-x", 0);
+	}
+	
+	public DeltaXProperty(java.lang.Object bean, double value) {
+		super(bean, "delta-x", value);
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/DeltaYProperty.java b/src/fr/inria/structgraphics/types/DeltaYProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ba7c87f9f77e20784850df94476a3fbca4344ae
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/DeltaYProperty.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.types;
+
+public class DeltaYProperty extends DistanceProperty {
+
+	public DeltaYProperty(java.lang.Object bean) {
+		super(bean, "delta-y", 0);
+	}
+	
+	public DeltaYProperty(java.lang.Object bean, double value) {
+		super(bean, "delta-y", value);
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/DistanceProperty.java b/src/fr/inria/structgraphics/types/DistanceProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..17bb6fd83cea89e68c43331baa4a5ff7a6191d71
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/DistanceProperty.java
@@ -0,0 +1,9 @@
+package fr.inria.structgraphics.types;
+
+public class DistanceProperty extends ConstrainedDoubleProperty {
+
+	public DistanceProperty(Object bean, String name, double val) {
+		super(bean, name, val);
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/DistributionProperty.java b/src/fr/inria/structgraphics/types/DistributionProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..89e1fd0dc622366b508543cfdf516d45b91dfd38
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/DistributionProperty.java
@@ -0,0 +1,62 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+
+public class DistributionProperty extends SimpleObjectProperty<DistributionProperty.Constraint> implements Shareable {
+
+	public enum Constraint {
+		None, Spacing, Distance 
+	}
+	
+	public DistributionProperty(Object bean, String name, DistributionProperty.Constraint value) {
+		super(bean, name, value);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(DistributionProperty.Constraint value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof DistributionProperty) {
+			return getValue().equals(((DistributionProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/DistributionXProperty.java b/src/fr/inria/structgraphics/types/DistributionXProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a2b4ea0cb1bd201d61ce84f71d8de6082648dff
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/DistributionXProperty.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.types;
+
+public class DistributionXProperty extends DistributionProperty {
+
+	public DistributionXProperty(Object bean) {
+		super(bean, "distribution-x", Constraint.None);
+	}
+	
+	public DistributionXProperty(Object bean, Constraint value) {
+		super(bean, "distribution-x", value);
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/DistributionYProperty.java b/src/fr/inria/structgraphics/types/DistributionYProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..371fe8b1ae2122b8cd309777b6f95c5f45bb99f9
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/DistributionYProperty.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.types;
+
+public class DistributionYProperty extends DistributionProperty {
+
+	public DistributionYProperty(Object bean) {
+		super(bean, "distribution-y", Constraint.None);
+	}
+	
+	public DistributionYProperty(Object bean, Constraint value) {
+		super(bean, "distribution-y", value);
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/DoubleListProperty.java b/src/fr/inria/structgraphics/types/DoubleListProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef3734b5743d0cee6d4561e40f4ac88b21e547c4
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/DoubleListProperty.java
@@ -0,0 +1,37 @@
+package fr.inria.structgraphics.types;
+
+import java.util.ArrayList;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.Property;
+import javafx.collections.FXCollections;
+
+public class DoubleListProperty extends FlexibleListProperty {
+
+	protected DoubleListProperty(Object bean, DoubleProperty property) {
+		super(bean, property.getName(), FXCollections.observableArrayList(new ArrayList<DoubleProperty>()));
+		add(property);
+	}
+		
+	public DoubleListProperty(Object bean, String name) {
+		super(bean, name, FXCollections.observableArrayList(new ArrayList<DoubleProperty>()));
+	}
+	
+	public double average() {
+		double sum = 0;
+		for(Property property:get()) {
+			sum += ((DoubleProperty)property).doubleValue();
+		}
+
+		return sum/size();
+	}
+	
+	public double variance(double mean) {
+		double sum = 0;
+		
+		for(Property property:get()) {
+			sum += Math.pow(((DoubleProperty)property).doubleValue() - mean, 2);
+		}
+
+		return sum/size();
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/FillColorProperty.java b/src/fr/inria/structgraphics/types/FillColorProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c77574bae901be3813cbc2062e227a750b4b1ba
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/FillColorProperty.java
@@ -0,0 +1,14 @@
+package fr.inria.structgraphics.types;
+
+import javafx.scene.paint.Color;
+
+public class FillColorProperty extends ColorProperty {
+
+	public FillColorProperty(java.lang.Object bean) {
+		super(bean, "fill", Color.WHITE);
+	}
+	
+	public FillColorProperty(java.lang.Object bean, Color col) {
+		super(bean, "fill", col);
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/FlexibleListProperty.java b/src/fr/inria/structgraphics/types/FlexibleListProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..e2b66988cddc643554bc999cb81e21c866284f4c
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/FlexibleListProperty.java
@@ -0,0 +1,440 @@
+package fr.inria.structgraphics.types;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.SortedSet;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.ui.inspector.util.PropertyCloner;
+import fr.inria.structgraphics.ui.utils.GroupBinding;
+import javafx.beans.binding.StringBinding;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleListProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.ObservableList;
+
+public class FlexibleListProperty extends SimpleListProperty<Property> implements Shareable {
+
+	private boolean protectFullName = false;
+	
+	protected FlexibleListProperty(Object bean, String name, ObservableList<Property> observableArrayList) {
+		super(bean, name, observableArrayList);
+	}
+
+	public static FlexibleListProperty createList(Object bean, Property property, boolean protectName) {
+		FlexibleListProperty list = createList(bean, property);
+		if(protectName) list.protectFullName = true;
+		return list;
+	}
+	
+	public static FlexibleListProperty createList(Object bean, List<Property> properties, boolean protectName) {
+		FlexibleListProperty list = createList(bean, properties);
+		if(protectName) list.protectFullName = true;
+		return list;
+	}
+	
+	
+	public static FlexibleListProperty createList(Object bean, Property property) {
+		FlexibleListProperty listProperty = null;
+		
+		if(property instanceof DoubleProperty) {
+			listProperty = new DoubleListProperty(bean, (DoubleProperty)property);
+		} else if(property instanceof RefProperty) {
+			listProperty = new ObjectListProperty(bean, (RefProperty)property);
+		} else if(property instanceof ColorProperty) {
+			listProperty = new ColorListProperty(bean, (ColorProperty)property);
+		} else if(property instanceof AlignmentProperty) {
+			listProperty = new ObjectListProperty(bean, (AlignmentProperty)property);
+		} else if(property instanceof ShapeProperty) {
+			listProperty = new ObjectListProperty(bean, (ShapeProperty)property);
+		} else if (property instanceof LineTypeProperty) {
+			listProperty = new ObjectListProperty(bean, (LineTypeProperty)property);
+		} else if(property instanceof DistributionProperty) {
+			listProperty = new ObjectListProperty(bean, (DistributionProperty)property);
+		}
+		else if(property instanceof TextProperty) {
+			listProperty = new StringListProperty(bean, (TextProperty)property);
+		}
+		else if(property instanceof FlexibleListProperty) {
+			listProperty = new NestedListProperty(bean, (FlexibleListProperty)property);
+		} else if(property instanceof StringProperty) {
+			listProperty = new StringListProperty(bean, (StringProperty)property);
+		}
+				
+		return listProperty;
+	}
+	
+	
+	public static FlexibleListProperty createList(Object bean, List<Property> properties) {
+		if(properties.isEmpty()) return null;
+		
+		FlexibleListProperty listProperty = createList(bean, properties.get(0));
+		for(int i=1; i<properties.size(); ++i)
+			listProperty.add(properties.get(i));
+		
+		return listProperty;
+	}
+	
+	/*
+	 * This was added to fix reassure that properties within groups appear with full name when shown within collections
+	 */
+	
+	@Override
+	public String getName() {
+		//System.err.println(super.getName() + "  " + getBean());
+		if(!protectFullName && getBean() instanceof VisGroup) return new PropertyName(super.getName()).getNoPostfixName();
+		else return super.getName();
+	}
+	
+	public void addEach(List<Property> properties) {
+		for(Property prop: properties)
+			add(prop);
+	}
+	
+	public void addEach(int index, List<Property> properties) {
+		for(Property prop: properties)
+			add(index, prop);
+	}
+	
+	public boolean allEqual() {
+		if(isEmpty()) return true;
+		
+		Object val = get(0).getValue();
+		for(int i = 1; i < size(); ++i ) {
+			if(!get(i).getValue().equals(val)) return false;
+		}
+		
+		return true;
+	}
+	
+	public Object firstValue() {
+		if(isEmpty()) return null;
+		else return get(0).getValue();
+	}
+	
+	public Object mode() {
+		HashMap<Object, Integer> map = new HashMap<>();
+		
+		// The integer value of the map will contain the number of occurences of the property value
+		for(Property property:get()) {
+			Object val = property.getValue();
+			if(map.containsKey(val)) 
+				map.put(val, map.get(val) + 1);
+			else map.put(val, 1);
+		}
+		
+		int max = 0;
+		Object val = null;
+		for(Object key: map.keySet()) {
+			int count = map.get(key);
+			if(count > max) val = key;
+		}
+		
+		return val;
+	}
+	
+	public PropertyName getPropertyName() {
+		return new PropertyName(getName());
+	}
+	
+	@Override
+	public Object getBean() {
+		Object object = super.getBean();
+		if(object instanceof Mark) {
+			Mark mark = (Mark)object;
+			if(mark.getContainer() instanceof VisGroup) {
+				return mark.getTopGroup();
+			}
+		}
+		
+		return super.getBean();
+	}
+	
+	/*
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPrefix(super.getName()); // TODO
+		} else return super.getName();
+	}*/
+
+	
+	public void bindElements(FlexibleListProperty property) {
+		for(int i = 0; i < size() && i < property.size(); ++i) {
+			Property prop1 = get(i);
+			Property prop2 = property.get(i);
+			
+			if(prop1 instanceof FlexibleListProperty) ((FlexibleListProperty)prop1).bindElements((FlexibleListProperty)prop2);
+			else prop1.bindBidirectional(prop2);
+		}
+	}
+
+	public void unbindElements(FlexibleListProperty property) {
+		for(int i = 0; i < size() && i < property.size(); ++i) {
+			Property prop1 = get(i);
+			Property prop2 = property.get(i);
+			
+			if(prop1 instanceof FlexibleListProperty) ((FlexibleListProperty)prop1).unbindElements((FlexibleListProperty)prop2);
+			else prop1.unbindBidirectional(prop2);
+		}
+	}
+	
+	
+	public String getValueAsString() {
+		StringBuffer buffer = new StringBuffer("[ ");
+		
+		String val;
+		Property property = get(0);
+		if(property instanceof FlexibleListProperty)
+			val = ((FlexibleListProperty)property).getValueAsString();
+		else val = property.getValue().toString();
+		
+		if(size() == 1) buffer.append(val);
+		else if(size() > 1) buffer.append(val + "... ");
+		
+		buffer.append(" ]");				
+		return buffer.toString();		
+	}
+	
+		
+	public boolean removeProperty(Property property) {
+		for(Property p: get()) {
+			if(p instanceof FlexibleListProperty) {
+				if(((FlexibleListProperty) p).removeProperty(property)) { 
+					return true;
+				} 
+			}
+			else if(remove(property)) {
+				return true;
+			}
+		}
+		
+		return false;
+	}
+	
+	
+	public List<FlexibleListProperty> transpose(){
+		List<FlexibleListProperty> list = new ArrayList<>();
+		
+		for(Property property:this) {
+			List<Property> flat; 
+			if(property instanceof NestedListProperty)
+				flat = ((NestedListProperty)property).flatten();	
+			else flat = ((FlexibleListProperty)property).getValue();
+			
+			for(int i = 0; i < flat.size(); ++i) {
+				FlexibleListProperty listProperty;// = list.get(i);
+				if(list.size() <= i) {
+					listProperty  = FlexibleListProperty.createList(getBean(), flat.get(i), protectFullName); // TODO: Check...
+					
+					list.add(listProperty);
+				} else {
+					listProperty = list.get(i);
+					listProperty.add(flat.get(i));
+				}
+			}
+		}
+
+		return list;
+	}
+	
+	
+	public List<Property> flatten(){
+		List<Property> list = new ArrayList<>();
+		
+		for(Property property:this) {
+			if(property instanceof NestedListProperty) {
+				list.addAll(((NestedListProperty)property).flatten());
+			}
+			else if(property instanceof FlexibleListProperty) {
+				list.addAll(((FlexibleListProperty)property).get());
+			}
+			else list.add(property);
+		}
+		
+		return list;
+	}
+	
+	
+	public FlexibleListProperty flattenFlex(){
+		FlexibleListProperty list = createList(getBean(), flatten(), protectFullName);
+		return list;
+	}
+	
+		
+	private Property getCompact(List<Mark> marks) {
+		VisCollection tmpgroup = null, vgroup = null;
+		boolean iscommon = false;
+		
+		for(Mark mark:marks) {
+			tmpgroup = null;
+			if(mark instanceof VisCollection) {
+				tmpgroup = (VisCollection)mark;
+				SortedSet<PropertyName> variable = tmpgroup.getChildPropertyStructure().getVariable();
+				if(variable.contains(getPropertyName())) {
+					vgroup = tmpgroup;
+					break;
+				}
+			}
+		}
+		
+		if(tmpgroup == null) return this;
+		if(vgroup == null) {
+			iscommon = true;
+			vgroup = (VisCollection)marks.get(0);
+		}
+		
+		if(iscommon && size() > 0) { 
+			Property property = get(0);
+			if(property instanceof FlexibleListProperty) {
+				return ((FlexibleListProperty)property).getCompact(vgroup.getComponentAt(0));
+			} else return property;
+		} else {
+			List<Property> list = new ArrayList<>();
+			for(Property property: this) {
+				if(property instanceof FlexibleListProperty) {
+					list.add(((FlexibleListProperty)property).getCompact(vgroup.getComponentAt(0)));
+				} else list.add(property);
+			}
+			
+			return createList(getBean(), list, protectFullName);
+		}				
+	}
+	
+	
+	public Property getCompact(Container refcontainer) {
+		if(!(refcontainer instanceof VisCollection)) return this; 
+		
+		SortedSet<PropertyName> common = ((VisCollection)refcontainer).getChildPropertyStructure().getCommon();
+		
+		if(common.contains(getPropertyName())) { 
+			Property property = get(0);
+			if(property instanceof FlexibleListProperty) {
+				return ((FlexibleListProperty)property).getCompact(refcontainer.getComponents());
+			} else return property;
+		} else {
+			List<Property> list = new ArrayList<>();
+			for(Property property: this) {
+				if(property instanceof FlexibleListProperty) {
+					list.add(((FlexibleListProperty)property).getCompact(refcontainer.getComponents()));
+				} else list.add(property);
+			}
+			return createList(getBean(), list, protectFullName);
+		}				
+	}
+	
+	
+	public Property getCompact2(Container refcontainer) {
+		if(!(refcontainer instanceof VisCollection)) return this; 
+		
+		SortedSet<PropertyName> common = ((VisCollection)refcontainer).getChildPropertyStructure().getCommon();
+		
+		List<Property> list = new ArrayList<>();
+		for(Property property: this) {
+			if(property instanceof FlexibleListProperty) {
+				list.add(((FlexibleListProperty)property).getCompact(refcontainer.getComponents()));
+			} else list.add(property);
+		}
+		return createList(getBean(), list, protectFullName);				
+	}
+	
+	public FlexibleListProperty getExtended() {
+		List<Property> list = new ArrayList<>();
+		
+		for(Property property : flatten()) {
+			Mark mark = (Mark)property.getBean();
+			int count = mark.leafs();
+			for(int i = 0 ; i < count; ++i)
+				list.add(property);
+		}
+		
+		return createList(getBean(), list, protectFullName);
+	}
+
+	
+	public boolean varies(Container container) {
+		if(!(container instanceof VisCollection)) return false;
+		
+		SortedSet<PropertyName> variable = ((VisCollection)container).getChildPropertyStructure().getVariable();
+		if(variable.contains(getPropertyName())) return true;
+		else {
+			for(Mark mark:container.getComponents()) {
+				if(varies(mark)) return true;
+			}
+			
+			return false;
+		}
+	}
+	
+	
+	// The following methods help to deal with the binding of groups of equally valued properties for groups
+	public ArrayList<GroupBinding> createGroupBindings(){
+		ArrayList<ArrayList<Property>> groupings = new ArrayList<>();
+		for(Property property: this) {
+			boolean found = false;
+			for(ArrayList<Property> grouping: groupings) {				
+				if(((Shareable)grouping.get(0)).isSimilar((Shareable)property) /*grouping.get(0).getValue().equals(property.getValue())*/) {
+					property.setValue(grouping.get(0).getValue());
+					grouping.add(property);
+					found = true;
+					break;
+				}
+			}
+			if(!found) {
+				ArrayList<Property> grouping = new ArrayList<>();
+				grouping.add(property);
+				groupings.add(grouping);
+			}
+		}
+		
+		ArrayList<GroupBinding> bindings = new ArrayList<>();
+		for(ArrayList<Property> grouping:groupings) {
+			GroupBinding binding = new GroupBinding(grouping);
+			bindings.add(binding);
+		}
+		
+		return bindings;
+	}
+
+	
+	@Override
+	public BooleanProperty getActiveProperty() {
+		if(isEmpty() || !(get(0) instanceof Shareable)) return new SimpleBooleanProperty(false);
+		else return ((Shareable)get(0)).getActiveProperty();		
+	}
+
+	@Override
+	public boolean isSimilar(Shareable property) {
+		return equals(property);
+	}
+
+	@Override
+	public BooleanProperty getPublicProperty() {
+		if(isEmpty() || !(get(0) instanceof Shareable)) return new SimpleBooleanProperty(false);
+		else return ((Shareable)get(0)).getPublicProperty();		
+	}
+
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		if(isEmpty() || !(get(0) instanceof Shareable)) return new SimpleBooleanProperty(false);
+		else return ((Shareable)get(0)).getHiddenProperty();
+	}
+
+	
+	public Property getByName(PropertyName pname) {
+		for(Property prop:this) {
+			String name_ = prop.getName();
+			if(name_ != null && pname.toString().equals(name_)) return prop;
+		}
+		
+		return null;
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/FontSizeProperty.java b/src/fr/inria/structgraphics/types/FontSizeProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..de7998b8473d0795db11dc6e0a14025f9d86a527
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/FontSizeProperty.java
@@ -0,0 +1,45 @@
+package fr.inria.structgraphics.types;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+
+public class FontSizeProperty extends SimpleDoubleProperty implements Shareable {
+
+	protected final static double EPSILON = .3;
+	
+	public FontSizeProperty(Object bean, double val) {
+		super(bean, "fontsize", val);
+	}
+
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof FontSizeProperty ) {
+			if(Math.abs(((FontSizeProperty ) property).get() - get()) < EPSILON) return true;
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/HeightProperty.java b/src/fr/inria/structgraphics/types/HeightProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..9620bd21c4a082dfa53c06eed98b0cc842ef721e
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/HeightProperty.java
@@ -0,0 +1,13 @@
+package fr.inria.structgraphics.types;
+
+public class HeightProperty extends DistanceProperty {
+
+	public HeightProperty(java.lang.Object bean) {
+		super(bean, "height", 0);		
+	}
+	
+	public HeightProperty(java.lang.Object bean, double value) {
+		super(bean, "height", value);		
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/IdentifierProperty.java b/src/fr/inria/structgraphics/types/IdentifierProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc5db4094f81a8a9d1ea67ccd9fce9707c263aff
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/IdentifierProperty.java
@@ -0,0 +1,51 @@
+package fr.inria.structgraphics.types;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleStringProperty;
+
+public class IdentifierProperty extends SimpleStringProperty implements Shareable {
+
+	public IdentifierProperty(Object bean, String name) {
+		super(bean, name);
+	}
+		
+	@Override 
+	public void setValue(String value) {
+		if(!value.equals(get())) super.setValue(value);
+		else {
+			fireValueChangedEvent();
+		}
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof IdentifierProperty) {
+			return getValue().equals(((IdentifierProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/LineTypeProperty.java b/src/fr/inria/structgraphics/types/LineTypeProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..2372aec7ced73fbc89a643ab36db515f0de18c72
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/LineTypeProperty.java
@@ -0,0 +1,61 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+
+public class LineTypeProperty extends SimpleObjectProperty<LineTypeProperty.Type> implements Shareable {
+	
+	public enum Type {
+		None, Straight, Bezier, StraightSolid, BezierSolid, Area, TopBottom
+	}
+	
+	public LineTypeProperty(Object bean, Type value) {
+		super(bean, "curve", value);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(LineTypeProperty.Type value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof LineTypeProperty) {
+			return getValue().equals(((LineTypeProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/NestedListProperty.java b/src/fr/inria/structgraphics/types/NestedListProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..b36b8c6d77140ee459dcc4aa1130f06e1776cc12
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/NestedListProperty.java
@@ -0,0 +1,21 @@
+package fr.inria.structgraphics.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javafx.beans.property.Property;
+import javafx.collections.FXCollections;
+
+public class NestedListProperty extends FlexibleListProperty {
+	
+	public NestedListProperty(Object bean, FlexibleListProperty property) {
+		super(bean, property.getName(), FXCollections.observableArrayList(new ArrayList<FlexibleListProperty>()));
+		add(property);
+	}
+
+
+	public FlexibleListProperty getPropertyList(int i) {
+		return (FlexibleListProperty)get(i);
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/ObjectListProperty.java b/src/fr/inria/structgraphics/types/ObjectListProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..087f00af071b95e2f546c6d10d663a4a5a911915
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ObjectListProperty.java
@@ -0,0 +1,14 @@
+package fr.inria.structgraphics.types;
+
+import java.util.ArrayList;
+import javafx.beans.property.ObjectProperty;
+import javafx.collections.FXCollections;
+
+public class ObjectListProperty extends FlexibleListProperty {
+
+	public ObjectListProperty(Object bean, ObjectProperty property) {
+		super(bean, property.getName(), FXCollections.observableArrayList(new ArrayList<ObjectProperty>()));
+		add(property);
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/types/OpacityProperty.java b/src/fr/inria/structgraphics/types/OpacityProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..65b900f2a1ba5702847c971764793c31af2c195e
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/OpacityProperty.java
@@ -0,0 +1,60 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+
+public class OpacityProperty extends SimpleDoubleProperty implements Shareable {
+
+	protected final static double EPSILON = .05;
+	
+	public OpacityProperty(Object bean, double val) {
+		super(bean, "opacity", val);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(Number value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof OpacityProperty) {
+			if(Math.abs(((OpacityProperty) property).get() - get()) < EPSILON) return true;
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/OrderProperty.java b/src/fr/inria/structgraphics/types/OrderProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..6f039709fa9643ceda1d016d71b3b539f6025b87
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/OrderProperty.java
@@ -0,0 +1,78 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnection;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+
+public class OrderProperty extends SimpleIntegerProperty implements Shareable {
+	
+	public OrderProperty(Object bean, int val) {
+		super(bean, "order", val);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(Number value) {
+		if(!value.equals(get())) super.setValue(value);
+		else {
+			fireValueChangedEvent();
+		}
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+	
+	public void updateValue(double value) {
+		this.setValue(value);
+	
+		if(getBean() instanceof Mark) {
+			Container container = ((Mark)getBean()).getContainer();
+			if(container instanceof VisBody) {
+				((VisBody)container).updateLayout((Mark)getBean());
+			}	
+		} else if(getBean() instanceof FlowConnection) {
+			Container container = ((FlowConnection)getBean()).getOrigin().getContainer();
+			if(container instanceof VisBody) {
+				((VisBody)container).updateLayout(((FlowConnection)getBean()).getOrigin());
+			}
+		}
+	}
+
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof OrderProperty) {
+			if(((OrderProperty) property).get() == get()) return true;
+		}
+		
+		return false;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/types/PropertyName.java b/src/fr/inria/structgraphics/types/PropertyName.java
new file mode 100644
index 0000000000000000000000000000000000000000..98a564cda0fe4e9d951113ac20eeba6a941e5b87
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/PropertyName.java
@@ -0,0 +1,238 @@
+package fr.inria.structgraphics.types;
+
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class PropertyName implements Comparable<PropertyName>{
+	
+	private static Map<String, Integer> order = createOrderMap();	
+	private static String prefixes = "ABCDEFGHIKLMNOP";
+	
+	private String name, groupingName, cleanName;
+	private int level = 0;
+	private String postfix = null; 
+	
+	public PropertyName(String name) { 
+		this.name = name;
+
+		groupingName = name.replaceAll("(\\.*[0-9]+)+", "");
+		
+		cleanName = name.replaceAll("[A-Z].", "").replaceAll("[0-9]+", "").replaceAll("\\.", "");
+
+		int index = name.indexOf(".");		
+		if(index >= 0) {
+			level = prefixes.indexOf(name.substring(0, index)) + 1;
+		}
+		else level = 0;
+		
+		Pattern p = Pattern.compile("[0-9]");
+		Matcher m = p.matcher(name);
+		if (m.find()) {
+			postfix = name.substring(m.start());
+		}
+	}
+
+	public static String getRegExpr(String varname) {
+		return "([A-Z]\\.)?" + varname;
+	}
+		
+	@Override
+	public int compareTo(PropertyName prop) {
+		int res = 0;
+		
+		if(postfix != null && prop.postfix != null) res = postfix.compareTo(prop.postfix);
+		
+		if(name.endsWith("id") && !prop.name.endsWith("id")) return -1;
+		else if(!name.endsWith("id") && prop.name.endsWith("id")) return 1;
+		else if(level < prop.level) return 1;
+		else if(level > prop.level) return -1;
+		else if(res != 0) return res;
+		else {
+			return PropertyName.order.get(cleanName) - PropertyName.order.get(prop.cleanName);
+		}
+	}
+	
+	@Override
+	public boolean equals(Object o) {
+		if(o instanceof PropertyName){
+			return name.equals(((PropertyName)o).name);
+		}
+		else return false;
+	}
+
+	@Override
+	public String toString() {
+		return name;
+	}
+	
+	public String getNoPostfixName() {
+		return groupingName;
+	}
+	
+	public String getCleanName() {
+		return cleanName;
+	}
+	
+	public static String getCleanName(String name) {
+		return name.replaceAll("[0-9]+", "").replaceAll("\\.[0-9]+", "");		
+	}
+
+	public int getLevel() {
+		return level;
+	}
+	
+	private static Map<String, Integer> createOrderMap(){
+		Map<String, Integer> map = new TreeMap<>();
+		map.put("id", 0);
+		map.put("order", 1);
+		map.put("source", 2);
+		map.put("destination", 3);
+		
+		map.put("weight", 4);
+		
+		map.put("text", 5);
+		map.put("fontsize", 7);
+		
+		map.put("sticky-x", 10);
+		map.put("sticky-y", 20);
+
+		map.put("distribution-x", 24);
+		map.put("delta-x", 25);		
+		
+		map.put("distribution-y", 26);
+		map.put("delta-y", 27);
+			
+		map.put("reference-x", 40);		
+		map.put("reference-y", 50);
+
+		map.put("x", 60);		
+		map.put("y", 70);
+		
+		map.put("min-x", 73);		
+		map.put("min-y", 74);
+				
+		map.put("width", 80);		
+		map.put("height", 90);
+		map.put("h-w ratio", 92);
+
+		map.put("shape", 94);
+		map.put("curve", 96);
+		
+		map.put("text", 102);
+		map.put("fontsize", 104);
+
+		map.put("coloring", 110);		
+		
+		map.put("fill", 112);		
+		map.put("stroke", 114);
+		map.put("opacity", 116);
+
+		
+		map.put("thickness", 120);		
+		map.put("rotation", 130);
+
+		return map;
+	}
+
+	public static String getPrefix(int level) {
+		return prefixes.charAt(level - 1) + ".";
+	}
+	
+	public String getPostfix() {
+		return postfix;
+	}
+	
+	public boolean isX() {
+		return cleanName.equals("x");
+	}
+	
+	public boolean isY() {
+		return cleanName.equals("y");
+	}
+	
+	public boolean isID() {
+		return cleanName.equals("id") || cleanName.equals("source") || cleanName.equals("destination"); 
+	}
+	
+	public boolean isWidth() {
+		return cleanName.equals("width");
+	}
+	
+	public boolean isHeight() {
+		return cleanName.equals("height");
+	}
+	
+	public boolean isText() {
+		return cleanName.equals("text");
+	}
+	
+	public boolean isFontSize() {
+		return cleanName.equals("fontsize");
+	}
+
+	public boolean isStickyX() {
+		return cleanName.equals("sticky-x");
+	}
+	
+	public boolean isStickyY() {
+		return cleanName.equals("sticky-y");
+	}
+	
+	public boolean isDistributionX() {
+		return cleanName.equals("distribution-x");
+	}
+	
+	public boolean isDistributionY() {
+		return cleanName.equals("distribution-y");
+	}
+	
+	public boolean isDeltaX() {
+		return cleanName.equals("delta-x");
+	}
+	
+	public boolean isDeltaY() {
+		return cleanName.equals("delta-y");
+	}
+	
+	public boolean isReferenceX() {
+		return cleanName.equals("reference-x");
+	}
+	
+	public boolean isReferenceY() {
+		return cleanName.equals("reference-y");
+	}
+	
+	public boolean isShape() {
+		return cleanName.equals("shape");
+	}
+	
+	public boolean isFill() {
+		return cleanName.equals("fill");
+	}
+	
+	public boolean isStroke() {
+		return cleanName.equals("stroke");
+	}
+	
+	public boolean isThickness() {
+		return cleanName.equals("thickness");
+	}
+	
+	public boolean isRotation() {
+		return cleanName.equals("rotation");
+	}
+	
+	public boolean isOpacity() {
+		return cleanName.equals("opacity");
+	}
+	
+	public boolean isColoring() {
+		return cleanName.equals("coloring");
+	}
+	
+	public boolean isCurve() {
+		return cleanName.equals("curve");
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/RatioLockProperty.java b/src/fr/inria/structgraphics/types/RatioLockProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ca6291521a0b80a8af2239c15e0c03fd1f61e25
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/RatioLockProperty.java
@@ -0,0 +1,57 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+
+public class RatioLockProperty extends SimpleBooleanProperty implements Shareable {
+
+	public RatioLockProperty(Object bean, String name, boolean val) {
+		super(bean, name, val);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(Boolean value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof RatioLockProperty) {
+			return getValue().equals(((RatioLockProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/RatioProperty.java b/src/fr/inria/structgraphics/types/RatioProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..8cc810e1b7d7f74de0eb3b32bcc36611be6b75cc
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/RatioProperty.java
@@ -0,0 +1,60 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+
+public class RatioProperty extends SimpleDoubleProperty implements Shareable {
+
+	protected final static double EPSILON = .1;
+	
+	public RatioProperty(Object bean, String name, double val) {
+		super(bean, name, val);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(Number value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof RatioProperty) {
+			if(Math.abs(((RatioProperty) property).get() - get()) < EPSILON) return true;
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/RefProperty.java b/src/fr/inria/structgraphics/types/RefProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..19fa1fbe7be44c7a2e9c6f7d0bc190ca95716207
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/RefProperty.java
@@ -0,0 +1,52 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+
+public class RefProperty<T> extends SimpleObjectProperty<T> implements Shareable {
+
+	public RefProperty(Object bean, String name, T value) {
+		super(bean, name, (T)value);
+	}
+
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof RefProperty) {
+			return getValue().equals(((RefProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/types/RotationProperty.java b/src/fr/inria/structgraphics/types/RotationProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..240c9ab736c337fde6936aed67ef7f0e157c140e
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/RotationProperty.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.types;
+
+public class RotationProperty extends AngleProperty {
+
+	public RotationProperty(java.lang.Object bean) {
+		super(bean, "rotation", 0);
+	}
+	
+	public RotationProperty(java.lang.Object bean, double value) {
+		super(bean, "rotation", value);
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/ShapeProperty.java b/src/fr/inria/structgraphics/types/ShapeProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c7db842dce273c1d426ec737c6eb2fbb02c02ec
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/ShapeProperty.java
@@ -0,0 +1,61 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+
+public class ShapeProperty extends SimpleObjectProperty<ShapeProperty.Type> implements Shareable {
+
+	public enum Type {
+		Rectangle, Ellipse, Triangle, Line, Text
+	}
+	
+	public ShapeProperty(Object bean, Type value) {
+		super(bean, "shape", value);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(ShapeProperty.Type value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof ShapeProperty) {
+			return getValue().equals(((ShapeProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/Shareable.java b/src/fr/inria/structgraphics/types/Shareable.java
new file mode 100644
index 0000000000000000000000000000000000000000..88211a08a758954333b5d36cc364c4c39d188735
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/Shareable.java
@@ -0,0 +1,11 @@
+package fr.inria.structgraphics.types;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.Property;
+
+public interface Shareable {	
+	public BooleanProperty getActiveProperty();
+	public boolean isSimilar(Shareable property);
+	public BooleanProperty getPublicProperty();
+	public BooleanProperty getHiddenProperty();
+}
diff --git a/src/fr/inria/structgraphics/types/StringListProperty.java b/src/fr/inria/structgraphics/types/StringListProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f380f2e822e8450f30ee7e7ccf6715cf7bd3c6e
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/StringListProperty.java
@@ -0,0 +1,14 @@
+package fr.inria.structgraphics.types;
+
+import java.util.ArrayList;
+import javafx.beans.property.StringProperty;
+import javafx.collections.FXCollections;
+
+public class StringListProperty extends FlexibleListProperty {
+
+	public StringListProperty(Object bean, StringProperty property) {
+		super(bean, property.getName(), FXCollections.observableArrayList(new ArrayList<StringProperty>()));
+		add(property);
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/types/StrokeColorProperty.java b/src/fr/inria/structgraphics/types/StrokeColorProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..efed3ac2fe458a585d3ee2198e9d1a2a2a8cb11b
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/StrokeColorProperty.java
@@ -0,0 +1,14 @@
+package fr.inria.structgraphics.types;
+
+import javafx.scene.paint.Color;
+
+public class StrokeColorProperty extends ColorProperty {
+
+	public StrokeColorProperty(java.lang.Object bean) {
+		super(bean, "stroke", Color.GRAY);
+	}
+	
+	public StrokeColorProperty(java.lang.Object bean, Color col) {
+		super(bean, "stroke", col);
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/StrokeWidthProperty.java b/src/fr/inria/structgraphics/types/StrokeWidthProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9cf0765719c9e1880458838fe9bcf1fc9c1c2ff
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/StrokeWidthProperty.java
@@ -0,0 +1,63 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+
+public class StrokeWidthProperty extends SimpleDoubleProperty  implements Shareable  {
+
+	protected final static double EPSILON = .1;
+	
+	public StrokeWidthProperty(Object bean) {
+		super(bean, "thickness", 1);
+	}
+	
+	public StrokeWidthProperty(Object bean, double val) {
+		super(bean, "thickness", val);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) { 
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(Number value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+	
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof StrokeWidthProperty ) {
+			if(Math.abs(((StrokeWidthProperty ) property).get() - get()) < EPSILON) return true;
+		}
+		
+		return false;
+	}
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/TextProperty.java b/src/fr/inria/structgraphics/types/TextProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..3fd0908f35e6cffbb047eee9e03f6832d7fa9c55
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/TextProperty.java
@@ -0,0 +1,57 @@
+package fr.inria.structgraphics.types;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleStringProperty;
+
+public class TextProperty extends SimpleStringProperty implements Shareable {
+	public TextProperty(java.lang.Object bean, String value) {
+		super(bean, "text", value);
+	}
+	
+	@Override
+	public String getName() {
+		if(getBean() instanceof Mark) {
+			return ((Mark)getBean()).getNestingPropertyName(super.getName());
+		} else return super.getName();
+	}
+	
+	@Override 
+	public void setValue(String value) {
+		if(!value.equals(get())) super.setValue(value);
+		else fireValueChangedEvent();
+	}
+	
+	private BooleanProperty activeProperty = new SimpleBooleanProperty(true);
+
+	@Override
+	public BooleanProperty getActiveProperty() {
+		return activeProperty;
+	}
+
+	@Override
+	public boolean isSimilar(Shareable property) {
+		if(property instanceof TextProperty) {
+			return getValue().equals(((TextProperty) property).getValue());
+		}
+		
+		return false;
+	}
+	
+	
+	
+	protected BooleanProperty publicProperty = new SimpleBooleanProperty(true);
+	
+	@Override
+	public BooleanProperty getPublicProperty() {
+		return publicProperty;
+	}
+	
+	protected BooleanProperty hiddenProperty = new SimpleBooleanProperty(false);
+	
+	@Override
+	public BooleanProperty getHiddenProperty() {
+		return hiddenProperty;
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/WidthProperty.java b/src/fr/inria/structgraphics/types/WidthProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..1648aee2141570e8754a50590e51f99c4994f56d
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/WidthProperty.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.types;
+
+public class WidthProperty extends DistanceProperty {
+
+	public WidthProperty(java.lang.Object bean) {
+		super(bean, "width", 0);
+	}
+	
+	public WidthProperty(java.lang.Object bean, double value) {
+		super(bean, "width", value);
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/XMinProperty.java b/src/fr/inria/structgraphics/types/XMinProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..44ac5c56523e046145c00e492b0c3650888f5344
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/XMinProperty.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.types;
+
+public class XMinProperty extends DistanceProperty {
+
+	public XMinProperty(java.lang.Object bean) {
+		super(bean, "min-x", 0);
+	}
+	
+	public XMinProperty(java.lang.Object bean, double value) {
+		super(bean, "min-x", value);
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/XProperty.java b/src/fr/inria/structgraphics/types/XProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..0674e2201ecb02dbd51877c9d0b62c43a9e83b20
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/XProperty.java
@@ -0,0 +1,14 @@
+package fr.inria.structgraphics.types;
+
+public class XProperty extends CoordinateProperty {
+
+	public XProperty(java.lang.Object bean) {
+		super(bean, "x", 0);
+	}
+	
+	public XProperty(java.lang.Object bean, double value) {
+		super(bean, "x", value);
+	}
+	
+
+}
diff --git a/src/fr/inria/structgraphics/types/YMinProperty.java b/src/fr/inria/structgraphics/types/YMinProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..842769ef0c0bcc50c199b62d1ea216c9c92dbeaa
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/YMinProperty.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.types;
+
+public class YMinProperty extends DistanceProperty {
+
+	public YMinProperty(java.lang.Object bean) {
+		super(bean, "min-y", 0);
+	}
+	
+	public YMinProperty(java.lang.Object bean, double value) {
+		super(bean, "min-y", value);
+	}
+}
diff --git a/src/fr/inria/structgraphics/types/YProperty.java b/src/fr/inria/structgraphics/types/YProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..27f99fcd9e4b38944f6c6326da2d0b07b2fd03e7
--- /dev/null
+++ b/src/fr/inria/structgraphics/types/YProperty.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.types;
+
+public class YProperty extends CoordinateProperty {
+
+	public YProperty(java.lang.Object bean) {
+		super(bean, "y", 0);
+	}
+	
+	public YProperty(java.lang.Object bean, double value) {
+		super(bean, "y", value);
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/DisplayPreferences.java b/src/fr/inria/structgraphics/ui/DisplayPreferences.java
new file mode 100644
index 0000000000000000000000000000000000000000..15238addcc092320e480a8af3bdd014dc8369c81
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/DisplayPreferences.java
@@ -0,0 +1,7 @@
+package fr.inria.structgraphics.ui;
+
+public class DisplayPreferences {
+
+	public final static double CANVAS_WIDTH = 1600, CANVAS_HEIGHT = 1400;
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/DragManager.java b/src/fr/inria/structgraphics/ui/DragManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..69f6b8264b0e98335ee995cb38ea5c0a654683c4
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/DragManager.java
@@ -0,0 +1,51 @@
+package fr.inria.structgraphics.ui;
+
+import fr.inria.structgraphics.ui.inspector.InspectorView;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.input.TransferMode;
+
+public class DragManager {
+	public final static String DRAG_CODE = "InFoGraPHeR";
+
+	private static DragManager instance;
+	
+	private InspectorView inspector;
+	
+	public DragManager(InspectorView inspector) {
+		this.inspector = inspector;
+	}
+	
+	public static DragManager create(InspectorView inspector) {
+		instance = new DragManager(inspector);
+		
+		return instance;
+	}
+	
+	public static DragManager getSingleton() {
+		return instance;
+	}
+	
+	public void observe(Draggable draggable) {
+		Node node = draggable.getNode();
+		
+        node.setOnDragDetected(
+        		new EventHandler<MouseEvent>() { public void handle(MouseEvent event) {
+                /* drag was detected, start a drag-and-drop gesture*/
+                /* allow any transfer mode */
+                Dragboard db = node.startDragAndDrop(TransferMode.COPY);
+//    System.err.println(draggable.getID());            
+                /* Put a string on a dragboard */
+                ClipboardContent content = new ClipboardContent();
+                content.putString(DRAG_CODE);
+                db.setContent(content);
+                inspector.setDraggable(draggable);
+                
+                event.consume();
+            }
+        });
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/Draggable.java b/src/fr/inria/structgraphics/ui/Draggable.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff11320e4da9b844d7e5254d355a1f739e1ddad6
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/Draggable.java
@@ -0,0 +1,26 @@
+package fr.inria.structgraphics.ui;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.PropertyName;
+import javafx.scene.Node;
+
+public interface Draggable {
+	
+	public enum Type {
+		Value, Table, Column
+	}
+
+	public VisBody getGroup();
+	public VisBody getTopGroup();
+	public Container getContainer();
+	public Node getNode();
+	public Type getType();
+	public Object getPropertiesContent();
+	public PropertyName getID();
+	public int getColumnsNum();
+	public int getRowsNum();
+	public void update();	
+	public boolean isInWide();
+	public boolean isNetwork();
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/BasePropertiesPane.java b/src/fr/inria/structgraphics/ui/inspector/BasePropertiesPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..6d1e4a66f5b383c2ddcd718b5964673dfa0eeefe
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/BasePropertiesPane.java
@@ -0,0 +1,82 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.Collection;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.ui.inspector.PropertiesTab.Type;
+import javafx.beans.property.Property;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+
+
+public class BasePropertiesPane extends PropertiesPane {
+	        
+    protected IndividualPropertiesGrid basegrid;
+    protected TitledIndividualPropertiesPane sharedpane;
+    
+    protected TitledTablePane tabularpane;
+    protected TabularPropertiesGrid fulltabularpane;
+
+    static PropertyDetail activeDetail;    
+    
+    protected Container node;
+    
+    public BasePropertiesPane(InspectorView inspector, String name, Container node) {
+    	this(inspector, name, node, Type.SELF);
+
+    }
+    
+    public BasePropertiesPane(InspectorView inspector, String name, Container node, Type type) {
+    	super(inspector, name);
+    	this.node = node;
+    	
+        getStyleClass().add("detail-pane");
+        setManaged(false);
+        setVisible(false);
+        setExpanded(false);
+        setMaxWidth(Double.MAX_VALUE);
+        setId("title-label");
+        setAlignment(Pos.CENTER_LEFT);
+        
+        if(type == Type.SELF || type == Type.GROUP || type == Type.PUBLIC) {
+            basegrid = new IndividualPropertiesGrid(node, type);
+            addPane(basegrid);
+        } else if(type == Type.CHILDREN) {
+            sharedpane = new TitledIndividualPropertiesPane("shared", new IndividualPropertiesGrid(node, type));
+            addPane(sharedpane);
+        }
+	}
+
+	protected void addToPane(final Node... nodes) {
+        if(basegrid != null) basegrid.addToPane(nodes);
+        else if(sharedpane != null) sharedpane.addToPane(nodes);
+    }
+    
+    @Override
+    protected void clearPane() {
+    	if(basegrid != null) basegrid.clearPane();
+    	if(sharedpane != null) sharedpane.clearPane();
+        if(tabularpane != null) tabularpane.clearPane();
+        if(fulltabularpane != null) fulltabularpane.clearPane();
+    }
+
+    @Override
+    public void addDetails(final Collection<Property> properties) {
+    	if(basegrid != null) basegrid.addDetails(properties);
+    	else if(sharedpane != null) sharedpane.addDetails(properties);
+    }
+    
+    
+    @Override
+    public void refresh() {
+    	if(basegrid != null) basegrid.refresh();
+    	if(sharedpane != null) sharedpane.refresh();
+    	if(tabularpane != null) tabularpane.refresh();
+    	if(fulltabularpane != null) fulltabularpane.refresh();
+    }
+
+    public void update() {
+    	refresh();
+    }
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/CollectionPropertiesPane.java b/src/fr/inria/structgraphics/ui/inspector/CollectionPropertiesPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..f8eb83bb83efb28100e9e4274ced7749a2e2b240
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/CollectionPropertiesPane.java
@@ -0,0 +1,172 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.Collection;
+import java.util.SortedSet;
+
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.DragManager;
+import fr.inria.structgraphics.ui.Draggable;
+import fr.inria.structgraphics.ui.inspector.PropertiesTab.Type;
+import fr.inria.structgraphics.ui.viscanvas.groupings.CollectionPropertyStructure;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.Property;
+import javafx.event.EventHandler;
+import javafx.scene.input.DragEvent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.TransferMode;
+
+public class CollectionPropertiesPane extends BasePropertiesPane {
+	        	
+	private CollectionPropertyStructure structure;
+	
+    public CollectionPropertiesPane(InspectorView inspector, String name, VisCollection node, Type type) {
+    	super(inspector, name, node, type);
+    	this.structure = node.getChildPropertyStructure();
+    	
+    	structure.getFlagProperty().addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				inspector.getPropertiesTable().updateStructures();
+			}
+		});
+    }
+       
+    // This adds the extended (detailed) tabular form
+    public void addExtendedTable(String name) { // TODO: This needs work !!!
+		PropertiesTable table = new PropertiesTable(name, structure, true, node);
+		fulltabularpane = new TabularPropertiesGrid(false);
+		fulltabularpane.addPropertiesTable(table);
+		
+		addPane(fulltabularpane);
+    }
+    
+	public void addTabDetails(String name) {
+		addDetails(structure.getMerged(), structure.getCommon());
+				
+		PropertiesTable table = new PropertiesTable(name, structure, node);
+		//tabularpane = new TabularPropertiesPane(name);
+		tabularpane = new TitledTablePane(name, new TabularPropertiesGrid(true));
+		tabularpane.addPropertiesTable(table);
+		addPane(tabularpane);
+				
+		sharedpane.setOnDragOver(new EventHandler<DragEvent>() {
+			
+		    public void handle(DragEvent event) {
+
+		    	Dragboard db = event.getDragboard();
+		  			    	
+		    	//TODO: I need to fix that so that it only activate when
+		        if (inspector.getDragged().getPropertiesContent() instanceof FlexibleListProperty && db.hasString() && !(inspector.getDragged() instanceof PropertyDetail)) {
+		            /* allow for both copying and moving, whatever user chooses */
+		            event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+		           		            
+		           // spreadsheetView.addEventHandler(MouseEvent.MOUSE_MOVED, eventHandler);		        
+		        }
+	            event.consume();
+		    }
+		});
+		
+		tabularpane.setOnDragOver(new EventHandler<DragEvent>() { 
+		    public void handle(DragEvent event) {
+		    	Dragboard db = event.getDragboard();
+		    	
+		    	//TODO: I need to fix that so that it only activate when
+		    	Draggable dragged = inspector.getDragged();
+		    	if(dragged == null) {
+		    		event.consume();
+		    		return;
+		    	}
+		    	
+		    	Object content = dragged.getPropertiesContent();
+		        if ((content instanceof ObjectProperty || content instanceof DoubleProperty || content instanceof FlexibleListProperty) && (inspector.getDragged() instanceof PropertyDetail) && db.hasString()  && inspector.getDragged().getID() != null) {
+		            /* allow for both copying and moving, whatever user chooses */
+		            event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+		           		            
+		           // spreadsheetView.addEventHandler(MouseEvent.MOUSE_MOVED, eventHandler);		        
+		        }
+	            event.consume();
+		    }
+		});
+		
+		
+		sharedpane.setOnDragDropped(new EventHandler <DragEvent>() {
+            public void handle(DragEvent event) {
+                /* data dropped */
+                /* if there is a string data on dragboard, read it and use it */
+                Dragboard db = event.getDragboard();
+                boolean success = false;
+                if (event.getGestureSource() != sharedpane && db.hasString() && db.hasString() && db.getString().equals(DragManager.DRAG_CODE)) {
+                	dragEnded(inspector.getDragged());
+                    success = true;
+                }
+                /* let the source know whether the string was successfully 
+                 * transferred and used */
+                event.setDropCompleted(success);
+                
+                event.consume();
+            }
+        });
+		
+		
+		tabularpane.setOnDragDropped(new EventHandler <DragEvent>() {
+            public void handle(DragEvent event) {
+                /* data dropped */
+                /* if there is a string data on dragboard, read it and use it */
+                Dragboard db = event.getDragboard();
+                boolean success = false;
+                if (db.hasString() && db.getString().equals(DragManager.DRAG_CODE)) {
+                	dragEnded(inspector.getDragged());
+                    success = true;
+                }
+                /* let the source know whether the string was successfully 
+                 * transferred and used */
+                event.setDropCompleted(success);
+                
+                event.consume();
+            }
+        });
+	}
+	
+ 
+	private void addDetails(Collection<Property> properties, SortedSet<PropertyName> common) {
+		sharedpane.addDetails(properties, common);
+	}
+
+	
+	@Override
+	public void update() {
+		if(sharedpane != null) sharedpane.clearPane();
+		
+		if(tabularpane !=null) {
+			addDetails(structure.getMerged(), structure.getCommon());
+			tabularpane.getTable().refresh();
+			tabularpane.refreshGrid();
+		} else if(fulltabularpane !=null) {
+			fulltabularpane.getTable().refresh();
+			fulltabularpane.refreshGrid();
+		}
+		
+		refresh();
+	}
+
+	
+	protected void dragEnded(Draggable dragged) {		
+		//Object content = dragged.getPropertiesContent();
+		if(dragged instanceof PropertyDetail) { // Need to move to the simple properties space		
+			structure.moveToVariable(dragged.getID());			
+		} else { // TODO: add it to the table
+			structure.moveToCommon(dragged.getID());
+			//inspector.getVisualizationFrame().update();
+		}			
+
+		// TODO...
+		// inspector.getPropertiesTable().updateStructures();
+	}
+	
+}
+
diff --git a/src/fr/inria/structgraphics/ui/inspector/ColorStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/ColorStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..b69d612c275b9f14e69c2fc7982ff5c5a2c78643
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/ColorStringConverter.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import javafx.scene.paint.Color;
+
+public class ColorStringConverter extends GeneralStringConverter {
+
+	@Override
+	public Object fromString(String string) {
+		return Color.web(string);
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/ColoringStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/ColoringStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..72399db2748db2c75bbe09423cfd00f07dcafc0c
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/ColoringStringConverter.java
@@ -0,0 +1,14 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.types.ColoringSchemeProperty;
+
+public class ColoringStringConverter extends GeneralStringConverter {
+
+	@Override
+	public Object fromString(String string) {
+		if(string.equalsIgnoreCase("common")) return ColoringSchemeProperty.Scheme.Common;
+		else if(string.equalsIgnoreCase("source")) return ColoringSchemeProperty.Scheme.Source;
+		else return ColoringSchemeProperty.Scheme.Destination;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/DisplayUtils.java b/src/fr/inria/structgraphics/ui/inspector/DisplayUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..561d862c2253644bd6fa035c8f6475d964b5d5e7
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/DisplayUtils.java
@@ -0,0 +1,101 @@
+/*
+ * Scenic View, 
+ * Copyright (C) 2012 Jonathan Giles, Ander Ruiz, Amy Fowler 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package fr.inria.structgraphics.ui.inspector;
+
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.util.*;
+import java.util.logging.*;
+
+import javafx.scene.image.Image;
+
+/**
+ * 
+ */
+public class DisplayUtils {
+
+	// From: https://www.flaticon.com/free-icon/cleaning_1215980
+	
+    private static final String CUSTOM_NODE_IMAGE = DisplayUtils.getNodeIcon("CustomNode").toString();
+    private static final Map<String, Image> loadedImages = new HashMap<>();
+
+    public static DecimalFormat DFMT = new DecimalFormat("0.0#");
+    private static Level wLevel;
+    private static Level wpLevel;
+
+    private static URL getNodeIcon(final String node) {
+        return InspectorView.class.getResource("icons/" + node + ".png");
+    }
+
+    public static Image getIcon(String type) {
+        Image image = loadedImages.get(type);
+        if (image == null) {
+            final URL resource = DisplayUtils.getNodeIcon(type);
+            String url;
+            if (resource != null) {
+                url = resource.toString();
+            } else {
+                url = CUSTOM_NODE_IMAGE;
+            }
+            image = new Image(url);
+            loadedImages.put(type, image);
+        }
+        return image;
+    }
+    
+    
+    public static Image getIcon(final VisualizationNode visNode) {
+        if (visNode.getIcon() != null)
+            return visNode.getIcon();
+        Image image = loadedImages.get(visNode.getType());
+        if (image == null) {
+            final URL resource = DisplayUtils.getNodeIcon(visNode.getType());
+            String url;
+            if (resource != null) {
+                url = resource.toString();
+            } else {
+                url = CUSTOM_NODE_IMAGE;
+            }
+            image = new Image(url);
+            loadedImages.put(visNode.getType(), image);
+        }
+        return image;
+    }
+
+    public static void showWebView(final boolean show) {
+        if (show) {
+            /**
+             * Ugly patch to remove the visual trace of the WebPane
+             */
+            final Logger webLogger = java.util.logging.Logger.getLogger("com.sun.webpane");
+            final Logger webPltLogger = java.util.logging.Logger.getLogger("webcore.platform.api.SharedBufferInputStream");
+            wLevel = webLogger.getLevel();
+            wpLevel = webPltLogger.getLevel();
+            webLogger.setLevel(Level.SEVERE);
+            webPltLogger.setLevel(Level.SEVERE);
+        } else {
+            Logger.getLogger("com.sun.webpane").setLevel(wLevel);
+            Logger.getLogger("webcore.platform.api.SharedBufferInputStream").setLevel(wpLevel);
+        }
+    }
+
+    public static Image getUIImage(final String image) {
+        return new Image(InspectorView.class.getResource("icons/" + image).toString());
+    }
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/DistributionStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/DistributionStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..509fc18aaf88b992764bf1f93726d3e3fa25fed8
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/DistributionStringConverter.java
@@ -0,0 +1,13 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+
+public class DistributionStringConverter extends GeneralStringConverter {
+
+	@Override
+	public Object fromString(String string) {
+		if(string.equalsIgnoreCase("none")) return Constraint.None;
+		else if(string.equalsIgnoreCase("spacing")) return Constraint.Spacing;
+		else return Constraint.Distance;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/DoubleStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/DoubleStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..38bc7f6cce72293e12b1d5ba0a41f6defcf4d95b
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/DoubleStringConverter.java
@@ -0,0 +1,27 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.text.DecimalFormat;
+
+public class DoubleStringConverter extends GeneralStringConverter {
+
+	private boolean decimals = false;
+
+	public DoubleStringConverter() {
+		this(false);
+	}
+	
+	public DoubleStringConverter(boolean decimals) {
+		this.decimals = decimals;
+	}
+		
+	@Override
+	public Object fromString(String string) {
+		return Double.parseDouble(string);
+	}
+
+	@Override
+	public String toString(Object object) { 
+		DecimalFormat df = new DecimalFormat(decimals ? "#.0" : "#"); 
+		return df.format((Double)object);
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/FlowConnectionsPane.java b/src/fr/inria/structgraphics/ui/inspector/FlowConnectionsPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..a367bab341be1d9cbba3a51630284167721da4be
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/FlowConnectionsPane.java
@@ -0,0 +1,54 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.ui.inspector.PropertiesTab.Type;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnections;
+
+public class FlowConnectionsPane extends BasePropertiesPane {
+	        	
+	private FlowConnections flowConnections;
+	
+    public FlowConnectionsPane(InspectorView inspector, String name, LineConnectedCollection node, Type type) {
+    	super(inspector, name, node, type);
+    	this.flowConnections = node.getFlowConnections();
+    	
+        sharedpane = new TitledIndividualPropertiesPane("visuals", new IndividualPropertiesGrid(node, type));
+        addPane(sharedpane);
+    	
+    	// TODO: Add something like that to observe changes!!!!
+    	/*
+    	flowConnections.getFlagProperty().addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				//inspector.getPropertiesTable().updateStructures();
+			}
+		});*/
+    }
+           
+    // This adds the extended (detailed) tabular form
+    public void addExtendedTable(String name) { // TODO: This needs work !!!
+
+		//tabularpane = new TabularPropertiesPane(name);
+		tabularpane = new TitledTablePane(name, new TabularPropertiesGrid(true));
+		FlowConnectionsTable table = new FlowConnectionsTable(name, flowConnections, node);
+		tabularpane = new TitledTablePane(name, new TabularPropertiesGrid(true));
+		tabularpane.addPropertiesTable(table);
+		
+		//fulltabularpane = new TabularPropertiesGrid(false);
+		//fulltabularpane.addPropertiesTable(table);
+		
+		addPane(tabularpane);
+    }
+    	
+	@Override
+	public void update() {
+		if(fulltabularpane !=null) {
+			fulltabularpane.getTable().refresh();
+			fulltabularpane.refreshGrid();
+		}
+		
+		refresh();
+	}
+
+}
+
diff --git a/src/fr/inria/structgraphics/ui/inspector/FlowConnectionsTable.java b/src/fr/inria/structgraphics/ui/inspector/FlowConnectionsTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6e75252da6c8df9a8e52d96c52bc188d7eca1d0
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/FlowConnectionsTable.java
@@ -0,0 +1,50 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.Map;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnections;
+
+public class FlowConnectionsTable extends PropertiesTable {
+
+	private FlowConnections flowConnections = null;
+		
+	public FlowConnectionsTable(String name, FlowConnections flowConnections, Container node) {
+		super(name, node);
+		
+		this.full = false;
+		this.flowConnections = flowConnections;
+		
+		props = flowConnections.getVariableList();
+		addEntries(props);
+	}
+	
+	@Override
+	protected void addEntries(Map<PropertyName, FlexibleListProperty>  tabproperties) {
+		for(PropertyName name: tabproperties.keySet()) {
+			FlexibleListProperty properties = tabproperties.get(name);
+
+			PropertyDetailColumn column = new FlowPropertyDetailColumn(this, properties, name, node);
+    		column.add(properties);
+    		add(column);	
+		}
+	}
+	
+	@Override
+	public boolean isNetwork() {
+		return true;
+	}
+	
+	@Override
+	public int getColumnsNum() { // TO Change
+		return 3;
+	}
+	
+	@Override
+	public int getRowsNum() {
+		if(flowConnections.isEmpty()) return 0;
+		else return flowConnections.size() + 1;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/FlowPropertyDetailColumn.java b/src/fr/inria/structgraphics/ui/inspector/FlowPropertyDetailColumn.java
new file mode 100644
index 0000000000000000000000000000000000000000..bca5752bb90493c61be4f37678be9f99a8462922
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/FlowPropertyDetailColumn.java
@@ -0,0 +1,22 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+
+public class FlowPropertyDetailColumn extends PropertyDetailColumn {
+	
+	private boolean isID = false;
+	
+	public FlowPropertyDetailColumn(FlowConnectionsTable table, FlexibleListProperty properties, PropertyName col, Container node) {
+		super(table, properties, col, node);
+		
+		isID = col.isID(); 
+	}
+					
+	@Override
+	public int getColumnsNum() {
+		return isID ? 2 : 1;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/GeneralStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/GeneralStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..192ba658bae96a6756d034f297f4e1cd7903a69d
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/GeneralStringConverter.java
@@ -0,0 +1,17 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import javafx.util.StringConverter;
+
+public class GeneralStringConverter extends StringConverter {
+
+	@Override
+	public String toString(Object object) {
+		return object.toString();
+	}
+
+	@Override
+	public Object fromString(String string) {
+		return string;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/GroupPropertiesPane.java b/src/fr/inria/structgraphics/ui/inspector/GroupPropertiesPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..03d04ef6d1e68b3767c9b840c401aa8692c81d1f
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/GroupPropertiesPane.java
@@ -0,0 +1,55 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.ui.inspector.PropertiesTab.Type;
+import fr.inria.structgraphics.ui.viscanvas.groupings.GroupPropertyStructure;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+
+public class GroupPropertiesPane extends BasePropertiesPane {
+	        	
+	private GroupPropertyStructure structure;
+	
+    public GroupPropertiesPane(InspectorView inspector, String name, VisGroup node, Type type) {
+    	super(inspector, name, node, type);
+    	this.structure = node.getChildPropertyStructure();
+    	
+    	structure.getFlagProperty().addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				inspector.getPropertiesTable().updateStructures();
+			}
+		});
+    }
+           
+	public void addTabDetails() {
+		basegrid.addDetails(structure);
+		//basegrid.addDetails(structure.getFlattenedProperties(), structure.getNames(), structure.getCommon());		
+	}
+		
+	@Override
+	public void update() {
+		if(basegrid  != null) {
+			basegrid.clearPane();
+			basegrid.addDetails(structure);
+		}
+		refresh();
+	}
+
+	
+	/*
+	protected void dragEnded(Draggable dragged) {
+		//Object content = dragged.getPropertiesContent();
+		if(dragged instanceof PropertyDetail) { // Need to move to the simple properties space		
+			structure.moveToVariable(dragged.getID());			
+		} else { // TODO: add it to the table
+			structure.moveToCommon(dragged.getID());
+			//inspector.getVisualizationFrame().update();
+		}			
+
+		// TODO...
+		// inspector.getPropertiesTable().updateStructures();
+	}*/
+	
+}
+
diff --git a/src/fr/inria/structgraphics/ui/inspector/IndividualPropertiesGrid.java b/src/fr/inria/structgraphics/ui/inspector/IndividualPropertiesGrid.java
new file mode 100644
index 0000000000000000000000000000000000000000..3fdfdf6253db932e95794811cdda9fb4444d3105
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/IndividualPropertiesGrid.java
@@ -0,0 +1,254 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.HeightProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.Shareable;
+import fr.inria.structgraphics.types.WidthProperty;
+import fr.inria.structgraphics.ui.DragManager;
+import fr.inria.structgraphics.ui.inspector.PropertiesTab.Type;
+import fr.inria.structgraphics.ui.viscanvas.groupings.DefaultSharingStrategy;
+import fr.inria.structgraphics.ui.viscanvas.groupings.GroupPropertyStructure;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.Property;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.EventHandler;
+import javafx.geometry.HPos;
+import javafx.geometry.Pos;
+import javafx.geometry.VPos;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.ColumnConstraints;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.text.Text;
+
+
+public class IndividualPropertiesGrid extends GridPane {
+	
+    private static final int LABEL_COLUMN = 0;
+    private static final int VALUE_COLUMN = 1;
+    private static final int LOCK_COLUMN = 2;
+	
+    static final String DETAIL_LABEL_STYLE = "detail-label";
+        
+    private List<PropertyDetail> details = new ArrayList<>();
+    
+    private Container node;
+    
+    private Type type;
+    
+    public IndividualPropertiesGrid(Container node, Type type) {
+    	super();
+    	
+    	this.node = node;
+    	this.type = type;
+    	
+        getStyleClass().add("detail-pane");
+        
+        getStyleClass().add("detail-grid");
+        setOnMousePressed(event -> {
+           if(BasePropertiesPane.activeDetail != null) BasePropertiesPane.activeDetail.recover();
+        });
+        
+        setHgap(4);
+        setVgap(2);
+        setSnapToPixel(true);
+ //       final ColumnConstraints colInfo = new ColumnConstraints(120);
+        
+        final ColumnConstraints colInfo = new ColumnConstraints(10);
+        getColumnConstraints().addAll(colInfo, new ColumnConstraints());        
+    }
+   
+    private void updateColumnWidth() {
+    	double w = 20;
+    	
+    	for(PropertyDetail detail: details) {
+        	Text theText = new Text(detail.label.getText());
+        	theText.setFont(detail.label.getFont());
+        	double width = theText.getBoundsInLocal().getWidth();
+        	w = Math.max(w, 20 + width);
+    	}
+    	
+    	getColumnConstraints().remove(0);
+    	getColumnConstraints().add(0, new ColumnConstraints(w));
+    }
+    
+    
+    private ChangeListener<Boolean> widthListener = null, heightListener = null;
+    
+    protected void addDetail(Property property, int row, PropertyName id, GroupPropertyStructure structure) {
+    	
+    	PropertyDetail detail;
+		detail = new PropertyDetail(property, false, type == Type.PUBLIC, id, node);
+ 		
+		// TODO: The source of the problem is here!!!
+        DragManager.getSingleton().observe(detail);
+
+        final HBox labelgroup = new HBox(8, detail.label);
+        labelgroup.setAlignment(Pos.TOP_RIGHT);
+        GridPane.setConstraints(labelgroup, LABEL_COLUMN, row);
+        GridPane.setHalignment(labelgroup, HPos.RIGHT);
+        GridPane.setValignment(labelgroup, VPos.TOP);
+        detail.label.getStyleClass().add(DETAIL_LABEL_STYLE);
+
+        final HBox valuegroup = new HBox(detail.valueLabel);
+        GridPane.setConstraints(valuegroup, VALUE_COLUMN, row);
+        GridPane.setHalignment(valuegroup, HPos.LEFT);
+        GridPane.setValignment(valuegroup, VPos.TOP);
+        detail.valueLabel.getStyleClass().add("detail-value");
+                        
+        // TODO:
+        if(type != Type.PUBLIC && (property instanceof HeightProperty || property instanceof WidthProperty) && id == null && (property.getBean() instanceof Mark)) { // This only concerns the Self Properties pane
+        	Mark mark = (Mark)property.getBean();
+        	
+         	detail.createLockIcon(mark.ratiolock.get(), property instanceof WidthProperty);
+        	
+         	labelgroup.getChildren().add(0, detail.lockIcon);
+         	
+        	detail.lockIcon.setOnMouseClicked(new EventHandler<MouseEvent>() {
+				@Override
+				public void handle(MouseEvent event) {
+					mark.ratiolock.set(!mark.ratiolock.get());
+					//detail.switchLock(mark.ratiolock.get());
+				}
+			});     
+        	
+        	
+        	if(property instanceof HeightProperty) {
+        		if(heightListener != null) mark.ratiolock.removeListener(heightListener);
+        		heightListener = new ChangeListener<Boolean>() {
+    				@Override
+    				public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+    					detail.switchLock(newValue);
+    				}
+    			};
+    			mark.ratiolock.addListener(heightListener);
+        	} else if (property instanceof WidthProperty) {
+           		if(widthListener != null) mark.ratiolock.removeListener(widthListener);
+           		widthListener = new ChangeListener<Boolean>() {
+    				@Override
+    				public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+    					detail.switchLock(newValue);
+    				}
+    			};
+    			mark.ratiolock.addListener(widthListener);
+        	}
+        }
+        else if(structure != null) {
+        	boolean flag = structure.getCommon().contains(id);
+        	detail.createExpandIcon(flag);
+        	labelgroup.getChildren().add(0, detail.lockIcon);
+        	detail.lockIcon.setOnMouseClicked(new EventHandler<MouseEvent>() {
+				@Override
+				public void handle(MouseEvent event) {
+					if(flag) structure.moveToVariable(id);
+					else structure.moveToCommon(id);
+					detail.switchLock(!flag);
+					
+					// Dirty solution to update the public properties
+					FlexibleListProperty property = structure.getProperties().get(id);
+					BooleanProperty prop = ((Shareable)property.get(0)).getPublicProperty();
+					prop.set(!prop.get());
+					prop.set(!prop.get());
+					
+					// Propagate change to groups under the same collection
+					// TODO: There is a problem when the properties of the siblings do not allow 
+					// for a sharing ... Do I need a way to force the sharing?
+					Object owner = property.getBean();
+					if(owner instanceof Mark) {
+						Container group = ((Mark)owner).getContainer();			
+						if(group instanceof VisCollection) {											
+							for(Mark mark: group.getComponents()) {
+								if(mark != owner && mark instanceof VisGroup) {
+									GroupPropertyStructure struct = ((VisGroup)mark).getChildPropertyStructure();
+									if(flag) struct.moveToVariable(id);
+									else struct.moveToCommon(id);
+									FlexibleListProperty property2 = structure.getProperties().get(id);
+									BooleanProperty prop2 = ((Shareable)property2.get(0)).getPublicProperty();
+									prop2.set(!prop2.get());
+									prop2.set(!prop2.get());
+								}
+							}
+							
+							// TODO: May contain bugs...Do other collections in the hierarchy need updating?
+							((VisCollection)group).getChildPropertyStructure().refresh(new DefaultSharingStrategy());
+						}
+					}
+				}
+			});  
+        }
+        
+        addToPane(labelgroup, valuegroup);
+        
+        details.add(detail);
+		updateColumnWidth();
+    }
+    
+    
+    protected void addToPane(final Node... nodes) {
+        getChildren().addAll(nodes);
+    }
+    
+    protected void clearPane() {
+        getChildren().clear();
+        details.clear();
+        // TODO....
+    }
+
+    public void addDetails(final Collection<Property> properties) {   
+        for(Property property: properties) {
+        	addDetail(property, null);
+        }
+    }
+    
+	public void addDetails(final Collection<Property> properties, Set<PropertyName> common) {
+		Iterator<PropertyName> iterator = common.iterator();
+		
+        for (Property property: properties) { // Hide non-shareable group properties
+        	if(property instanceof Shareable && (!((Shareable) property).getPublicProperty().get()
+        			|| ((Shareable) property).getHiddenProperty().get())) {
+        		iterator.next();
+        		continue;
+        	}
+        	else addDetail(property, iterator.next());
+        }
+	}
+		
+	public void addDetails(GroupPropertyStructure structure) {
+		// TODO Auto-generated method stub
+	
+		Iterator<PropertyName> iterator = structure.getNames().iterator();
+        for (Property property: structure.getFlattenedProperties()) {
+        	PropertyName name = iterator.next();
+            addDetail(property, details.size(), name, structure);            
+        }
+	}
+    
+    public void addDetail(Property detail, PropertyName id) { //System.err.println(id + " " + detail);
+    	addDetail(detail, details.size(), id, null);
+    }
+
+    public void refresh() {
+        for (int i = 0; i < details.size(); i++) {
+            details.get(i).refresh();           
+        }
+    }
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/InspectorView.java b/src/fr/inria/structgraphics/ui/inspector/InspectorView.java
new file mode 100644
index 0000000000000000000000000000000000000000..deb1f36cc807bf6e8b40f3117544cb4d28b106a0
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/InspectorView.java
@@ -0,0 +1,143 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.ArrayList;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.ui.Draggable;
+import fr.inria.structgraphics.ui.spreadsheet.DataView;
+import fr.inria.structgraphics.ui.tools.SelectTool;
+import javafx.scene.control.SplitPane;
+import javafx.scene.control.TabPane;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.StackPane;
+
+public class InspectorView extends BorderPane {
+
+    public static final String STYLESHEETS = InspectorView.class.getResource("inspector.css").toExternalForm();
+	
+	private SplitPane splitPane;
+	private VisualizationTreeView treeView;
+	private TabPane tabPane;
+	private PropertiesTab propertiesTab;
+	private SyntaxTab syntaxTab;
+
+	private VisFrame visframe;
+	
+	private Draggable dragged = null;
+	
+	private DataView dataView;
+	
+	public InspectorView() {
+		buildUI();
+	}	
+	
+	private void buildUI() {
+        // main splitpane
+        splitPane = new SplitPane();
+        splitPane.setId("splitpane");
+		
+        treeView = new VisualizationTreeView(this);
+        treeView.setId("treeview");
+        
+        StackPane treeViewStackPane = new StackPane(treeView);
+        treeViewStackPane.setStyle(" -fx-padding: 0");
+        treeView.setMaxHeight(Double.MAX_VALUE);
+        
+        tabPane = new TabPane();
+        propertiesTab = new PropertiesTab(this);
+        tabPane.getTabs().add(propertiesTab);
+        
+        
+        // TODO: I do not care about syntax for now...
+     //   syntaxTab = new SyntaxTab(this);
+     //   tabPane.getTabs().add(syntaxTab);
+           
+        splitPane.setDividerPosition(0, 0.3);
+        splitPane.getItems().addAll(treeViewStackPane, tabPane);
+        
+        this.setCenter(splitPane);
+	}
+	
+	public void setVisualizationFrame(VisFrame visframe) {
+		this.visframe = visframe;
+		visframe.setInspector(this);
+		
+		// TODO: No handling syntax for now 
+		// syntaxTab.setSyntax(visframe.getSyntax());
+	}
+	
+	public void update() {
+		propertiesTab.cleanAll();
+		treeView.update(visframe);
+	}
+	
+	public void updateOrder() {
+		propertiesTab.cleanAll();
+		treeView.updateOrder();
+		dataView.update();
+	}
+		
+	public VisFrame getVisualizationFrame() {
+		return visframe;
+	}
+	
+	
+	public void refresh() {
+	//	propertiesTab.cleanAll();
+	//	treeView.refreshProperties(visframe);
+	}
+	
+	public PropertiesTab getPropertiesTable() {
+		return propertiesTab;
+	}
+
+	public void setView(ArrayList<Mark> marks) {
+		treeView.setActiveNodes(marks);
+	}
+	
+	public void setView(Mark mark) {
+		treeView.setActiveNode(mark);
+	}
+	
+	public void updateTreeViewLabel(Mark mark) {
+		treeView.updateLabel(mark);
+	}
+	
+	public void selectView(Container node) {
+	//	treeView.selectView(node);
+	//	propertiesTab.setActiveNode(node);
+	}
+	
+	public void generateView(Container node) {
+		propertiesTab.publishNode(node);
+	}
+
+	public void updateCollectionViews(VisCollection collection) {
+		propertiesTab.publishNode(collection);
+		for(Mark mark:collection.getComponents()) {
+			if(mark instanceof VisCollection)
+				updateCollectionViews((VisCollection)mark);
+		}
+	}
+	
+	public void setDraggable(Draggable draggable) {
+		dragged = draggable;
+	}
+	
+	public Draggable getDragged() {
+		return dragged;
+	}
+
+	public void setSelector(SelectTool select) {
+		treeView.setSelector(select);
+	}
+
+	public void setDataView(DataView dataView) {
+		this.dataView = dataView;
+		
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/LineTypeStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/LineTypeStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..f3f90417f19f4038a28d4e388046ee7371c4e102
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/LineTypeStringConverter.java
@@ -0,0 +1,17 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.types.LineTypeProperty.Type;
+
+public class LineTypeStringConverter extends GeneralStringConverter {
+
+	@Override
+	public Object fromString(String string) {
+		if(string.equalsIgnoreCase("None")) return Type.None;
+		else if(string.equalsIgnoreCase("StraightSolid")) return Type.StraightSolid;
+		else if(string.equalsIgnoreCase("Straight")) return Type.Straight;
+		else if(string.equalsIgnoreCase("Bezier")) return Type.Bezier;
+		else if(string.equalsIgnoreCase("BezierSolid")) return Type.BezierSolid;
+		else if(string.equalsIgnoreCase("TopBottom")) return Type.TopBottom;
+		else /*if(string.equalsIgnoreCase("Area")*/ return Type.Area;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/ListStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/ListStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..c3f6de7167c2919f8d22e72f4ee4c7758a133476
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/ListStringConverter.java
@@ -0,0 +1,28 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javafx.beans.property.Property;
+import javafx.util.StringConverter;
+
+public class ListStringConverter extends StringConverter<List<Property>> {
+
+	@Override
+	public String toString(List<Property> list) {
+		StringBuffer buffer = new StringBuffer("[ ");
+		
+		if(list.size() == 1) buffer.append(list.get(0).getValue());
+		else if(list.size() > 1) buffer.append(list.get(0).getValue() + "... ");
+		
+		buffer.append(" ]");
+		
+		return buffer.toString();
+	}
+
+	@Override
+	public List<Property> fromString(String string) {
+		return new ArrayList<>(); // TODO: This is not useful. Not sure if it will be eventually used...
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/PropertiesPane.java b/src/fr/inria/structgraphics/ui/inspector/PropertiesPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..0127f61b15bdaad08b0f072371b393cc9d260e2e
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/PropertiesPane.java
@@ -0,0 +1,40 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.Collection;
+
+import javafx.beans.property.Property;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.control.TitledPane;
+import javafx.scene.layout.VBox;
+
+public abstract class PropertiesPane extends TitledPane {
+    
+    protected InspectorView inspector;
+    private VBox box;
+    
+    public PropertiesPane(InspectorView inspector, String name) {
+    	super();
+
+    	this.inspector = inspector;
+    	setText(name);    	
+    	
+    	box = new VBox();
+    	setContent(box);
+    }
+    
+    public void addPane(Node node) {
+    	box.getChildren().add(node);
+    }
+    
+    public void addGap() {
+    	box.getChildren().add(new Label("             "));
+    }
+    
+    public abstract void addDetails(final Collection<Property> details);
+    
+    protected abstract void clearPane();    
+    public abstract void refresh();
+    public abstract void update();
+    
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/PropertiesTab.java b/src/fr/inria/structgraphics/ui/inspector/PropertiesTab.java
new file mode 100644
index 0000000000000000000000000000000000000000..de03d8b6de6c6c1db31df9cb33ebf8acdf17d56f
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/PropertiesTab.java
@@ -0,0 +1,288 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.Shareable;
+import fr.inria.structgraphics.ui.viscanvas.groupings.CollectionPropertyStructure;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnections;
+import javafx.beans.property.Property;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.Tab;
+import javafx.scene.layout.VBox;
+
+public class PropertiesTab extends Tab {
+	
+	public enum Type {
+		SELF, CHILDREN, TABLE, GROUP, PUBLIC, CONNECTION_TABLE
+	}
+	
+	public static final String TAB_NAME = "Properties Structure";
+	private InspectorView inspector;
+	
+	private Container activeNode = null;
+	
+    private Hashtable<NodeEntry, PropertiesPane> propertiesPanes = new Hashtable<NodeEntry, PropertiesPane>();
+    
+    private VBox vbox;
+
+	public PropertiesTab(InspectorView inspector) {
+		super(TAB_NAME);
+			
+		this.inspector = inspector;
+		
+        ScrollPane scrollPane = new ScrollPane();
+        //scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
+        scrollPane.setFitToWidth(true);
+        vbox = new VBox();
+        vbox.setFillWidth(true);
+        scrollPane.setContent(vbox);
+        getStyleClass().add("all-details-pane");
+        
+        setContent(scrollPane);
+        setClosable(false);
+	}
+	
+
+	public void setActiveNode(Container node) {
+		if(activeNode == node) return;
+		else clean();
+
+		PropertiesPane pane = getPane(node, Type.SELF);
+        pane.setExpanded(true);
+        pane.setManaged(true);
+        pane.setVisible(true);        
+        
+        //////////
+        if(node instanceof VisCollection) { // TODO: Deal with Groups!!!!!
+        	pane = getPane(node, Type.CHILDREN);
+            pane.setExpanded(true);
+            pane.setManaged(true);
+            pane.setVisible(true);
+            
+        	pane = getPane(node, Type.TABLE);
+            pane.setExpanded(true);
+            pane.setManaged(true);
+            pane.setVisible(true);
+            
+            // For Top collections show the connections if available
+            if(node instanceof LineConnectedCollection) {
+            	FlowConnections connections = ((LineConnectedCollection) node).getFlowConnections();
+            	if(connections != null && !connections.isEmpty()) {
+            		pane = getPane(node, Type.CONNECTION_TABLE);
+                    pane.setExpanded(true);
+                    pane.setManaged(true);
+                    pane.setVisible(true);
+            	}
+            }
+        } 
+        else if(node instanceof VisGroup && !(((VisGroup) node).getContainer() instanceof VisGroup)) {
+        	pane = getPane(node, Type.GROUP);
+            pane.setExpanded(true);
+            pane.setManaged(true);
+            pane.setVisible(true);
+            
+        	pane = getPane(node, Type.PUBLIC);
+        	pane.setExpanded(true);
+        	pane.setManaged(true);
+        	pane.setVisible(true);  
+        }
+	}
+	
+	
+	public void publishNode(Container node) {
+		if(node instanceof VisGroup && !(((VisGroup) node).getContainer() instanceof VisGroup)) {
+        	createPane(node, Type.PUBLIC);
+        }
+		
+        createPane(node, Type.SELF);
+  
+        if(node instanceof VisCollection) {
+        	createPane(node, Type.CHILDREN);
+        	createPane(node, Type.TABLE);
+        	
+        	if(node.hasConnections()) createPane(node, Type.CONNECTION_TABLE);
+        }
+        else if (node instanceof VisGroup && !(((VisGroup) node).getContainer() instanceof VisGroup)) {
+        	createPane(node, Type.GROUP);
+        }
+	}
+	
+	
+    private void createPane(Container node, Type type) {
+    	String paneName = "";
+    	
+    	if(type == Type.SELF)
+    		paneName = "Self Properties";
+    	else if(type == Type.CHILDREN)
+    		paneName = "Children Properties";
+    	else if(type == Type.GROUP)
+    		paneName = "Children Properties";
+    	else if(type == Type.TABLE)
+    		paneName = "Tabular Structure";
+    	else if(type == Type.PUBLIC)
+    		paneName = "Public (Visible to Collections)";
+    	else if(type == Type.CONNECTION_TABLE)
+    		paneName = "Flow Connections";
+    	
+        NodeEntry nodeEntry = new NodeEntry(node, paneName);
+        
+        if(type == Type.SELF) {
+        	BasePropertiesPane pane = new BasePropertiesPane(inspector,paneName, node);
+        	propertiesPanes.put(nodeEntry, pane);
+        	Collection<Property> properties = node.getSelfProperties().values();
+        
+        	pane.addDetails(properties);  
+        }
+        else if(type == Type.CHILDREN) { // TODO: Deal with Groups!!!!!
+        	CollectionPropertiesPane pane = new CollectionPropertiesPane(inspector, paneName, (VisCollection)node, type);
+        	propertiesPanes.put(nodeEntry, pane);
+        	pane.addTabDetails("variable"); 
+        }
+        else if(type == Type.TABLE) {
+        	CollectionPropertiesPane pane = new CollectionPropertiesPane(inspector, paneName, (VisCollection)node, type);
+        	propertiesPanes.put(nodeEntry, pane);
+        	pane.addExtendedTable("full tabular structure"); 
+        } else if(type == Type.GROUP) {
+        	GroupPropertiesPane pane = new GroupPropertiesPane(inspector, paneName, (VisGroup)node, type);
+        	propertiesPanes.put(nodeEntry, pane);
+        	pane.addTabDetails();
+        } else if(type == Type.PUBLIC) {
+        	BasePropertiesPane pane = new BasePropertiesPane(inspector, paneName, node, type);
+        	propertiesPanes.put(nodeEntry, pane);
+        	
+    		ArrayList<Property> publicProperties = new ArrayList<>();
+    		ArrayList<Property> allProperties = new ArrayList<>();
+        	((VisGroup)node).splitProperties(publicProperties, allProperties);
+        	pane.addDetails(publicProperties);  
+        	
+        	addVisibilityListeners(allProperties, pane, (VisGroup)node);
+        } else if(type == Type.CONNECTION_TABLE) {   	
+        	// TODO:...
+        	FlowConnectionsPane pane = new FlowConnectionsPane(inspector, paneName, (LineConnectedCollection)node, type);
+        	propertiesPanes.put(nodeEntry, pane);
+        	
+        	Collection<Property> properties = new ArrayList<>();
+        	properties.add(((LineConnectedCollection)node).coloringScheme);
+        	properties.add(((LineConnectedCollection)node).flowPaint);
+        	properties.add(((LineConnectedCollection)node).flowOpacity);
+        	pane.addDetails(properties);
+        	
+        	pane.addExtendedTable("structure"); 
+        }
+    }
+    
+    private void addVisibilityListeners(ArrayList<Property> properties, BasePropertiesPane pane, VisGroup group) {
+    	ChangeListener<Boolean> listener = new ChangeListener<Boolean>() {
+			@Override
+			public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+				pane.clearPane();
+	    		ArrayList<Property> publicProperties = new ArrayList<>();
+	    		ArrayList<Property> allProperties = new ArrayList<>();
+	        	group.splitProperties(publicProperties, allProperties);
+	        	pane.addDetails(publicProperties);  
+			}
+		};
+    	
+    	for(Property property:properties) {
+   			((Shareable)property).getPublicProperty().addListener(listener);
+    	}
+    }
+	
+    public void updateStructures() {    	
+    	for(PropertiesPane pane:propertiesPanes.values())
+    		pane.update();
+    }
+ 
+    
+	private void clean() {
+		vbox.getChildren().clear();
+		//propertiesPanes.clear();
+	}
+	
+	public void cleanAll() {
+		vbox.getChildren().clear();
+		propertiesPanes.clear();
+	}
+	
+    private PropertiesPane getPane(Container node, Type type) {
+    	String paneName = "";
+    	
+    	if(type == Type.SELF)
+    		paneName = "Self Properties";
+    	else if(type == Type.CHILDREN)
+    		paneName = "Children Properties";
+    	else if(type == Type.TABLE)
+    		paneName = "Tabular Structure";
+    	else if(type == Type.GROUP)
+    		paneName = "Children Properties";
+    	else if(type == Type.PUBLIC)
+    		paneName = "Public (Visible to Collections)";
+    	else if(type == Type.CONNECTION_TABLE)
+    		paneName = "Flow Connections";
+    	
+        NodeEntry nodeEntry = new NodeEntry(node, paneName);
+        PropertiesPane pane = propertiesPanes.get(nodeEntry);
+       
+        vbox.getChildren().add(pane);
+        pane.refresh();
+        
+        return pane;
+    }
+    
+       
+    class NodeEntry {
+    	private Container node;
+    	private String name;
+    	
+    	public NodeEntry(Container node, String name) {
+    		this.node = node;
+    		this.name = name;
+    	}
+    	
+    	public Container getNode() {
+    		return node;
+    	}
+    	
+    	public String getName() {
+    		return name;
+    	}
+    	
+    	@Override
+    	public boolean equals(Object obj) {
+    		if(obj instanceof NodeEntry) {
+    			NodeEntry entry = (NodeEntry)obj;
+    			    			
+    			return entry.node == this.node && entry.name.equals(this.name);
+    		}
+    		else return false;
+    	}
+
+		@Override
+		public int hashCode() {
+			return name.hashCode() + 31*node.hashCode();
+		}
+    	
+  
+    }
+
+
+
+
+    
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/PropertiesTable.java b/src/fr/inria/structgraphics/ui/inspector/PropertiesTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b7d3d931a3ea20b09b3e735ca2701eccd0448e2
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/PropertiesTable.java
@@ -0,0 +1,136 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.Draggable;
+import fr.inria.structgraphics.ui.viscanvas.groupings.CollectionPropertyStructure;
+import javafx.scene.Node;
+
+public class PropertiesTable extends ArrayList<PropertyDetailColumn> implements Draggable {
+
+	private String name = null;
+	private CollectionPropertyStructure structure = null;
+	protected boolean full = false;
+	private Node handle;
+	protected Map<PropertyName, FlexibleListProperty> props;
+	protected Container node;
+	
+	public PropertiesTable(String name, CollectionPropertyStructure structure, Container node) {
+		this(name, structure, false, node);
+	}
+	
+	public PropertiesTable(String name, CollectionPropertyStructure structure, boolean full, Container node) {
+		this(name, node);
+		this.structure = structure;
+		this.full = full;
+		
+		props = full ? structure.getFullVariableList() : structure.getVariableList();
+		addEntries(props);
+	}
+	
+	public PropertiesTable(String name, Container node) {
+		this.name = name;
+		this.node = node;
+	}
+	
+	public String getName() {
+		return name;
+	}
+		
+	public FlexibleListProperty getProperties(PropertyName col){
+		return props.get(col);//structure.getProperties().get(col);
+	}
+	
+	protected void addEntries(Map<PropertyName, FlexibleListProperty>  tabproperties) {
+		for(FlexibleListProperty properties: tabproperties.values()) {
+    		PropertyDetailColumn column = new PropertyDetailColumn(this, properties, new PropertyName(properties.getName()), node);
+    		column.add(properties);
+    		add(column);	
+		}
+	}
+	
+	public void refresh() {
+		clear();
+		props = full ? structure.getFullVariableList() : structure.getVariableList();
+		addEntries(props);
+	}
+	
+	@Override
+	public int getColumnsNum() {
+		int counter = 0;
+		
+		for(PropertyDetailColumn column:this) {
+			counter += column.getColumnsNum();
+		}
+		
+		return counter;
+	}
+	
+	@Override
+	public int getRowsNum() {
+		if(isEmpty()) return 0;
+		else return get(0).size() + 1;
+	}
+	
+	public void setHandle(Node node) {
+		this.handle = node;
+	}
+
+	@Override
+	public Node getNode() {
+		return handle;
+	}
+
+	@Override
+	public Type getType() {
+		return Type.Table;
+	}
+
+	@Override
+	public Object getPropertiesContent() {
+		return props.values();
+	}
+
+	@Override
+	public void update() {
+		for(PropertyDetailColumn column:this)
+			column.update();
+	}
+
+	@Override
+	public PropertyName getID() {
+		// TODO Auto-generated method stub
+		return new PropertyName("");
+	}
+
+	@Override
+	public VisBody getTopGroup() {
+		return node.getRootVirtualGroup();
+	}
+
+	@Override
+	public VisBody getGroup() {
+		return node.getVirtualGroup();
+	}
+	
+	@Override
+	public Container getContainer() {
+		return node;
+	}
+
+	@Override
+	public boolean isInWide() {
+		return !full;
+	}
+
+	@Override
+	public boolean isNetwork() {
+		return false;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/PropertyDetail.java b/src/fr/inria/structgraphics/ui/inspector/PropertyDetail.java
new file mode 100644
index 0000000000000000000000000000000000000000..0927815e3239a75f57adc30f1e1be19d3f76e9b2
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/PropertyDetail.java
@@ -0,0 +1,582 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.binding.Bindings;
+import javafx.beans.binding.StringBinding;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.ColorPicker;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.ContentDisplay;
+import javafx.scene.control.Control;
+import javafx.scene.control.Label;
+import javafx.scene.control.Slider;
+import javafx.scene.control.TextField;
+import javafx.scene.control.Tooltip;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.HBox;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.util.Duration;
+import javafx.util.StringConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.ColoringSchemeProperty;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.LineTypeProperty;
+import fr.inria.structgraphics.types.OpacityProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.RotationProperty;
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.types.Shareable;
+import fr.inria.structgraphics.types.StrokeWidthProperty;
+import fr.inria.structgraphics.types.AlignmentProperty.XSticky;
+import fr.inria.structgraphics.types.AlignmentProperty.YSticky;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import fr.inria.structgraphics.ui.Draggable;
+import fr.inria.structgraphics.ui.inspector.detailmodel.SimpleSerializer;
+import fr.inria.structgraphics.ui.inspector.util.TooltipCreator;
+
+public class PropertyDetail implements Draggable {
+
+	public enum EditionType {
+		COMBO, SLIDER, COLOR_PICKER, TEXT, NONE
+	};
+
+    private List<Property> properties;    
+	public Label label;
+	private List<SimpleSerializer> serializers = new ArrayList<>();
+	
+	public HBox valueLabel = new HBox(4);
+	private Node graphic_unlock, graphic_lock;
+	public Label lockIcon = null;
+
+    private double min, max;
+    
+    private EditionType editionType = EditionType.TEXT;
+    
+    private Object[] validItems; // TODO: Not sure if used for any type of data. Let's see.
+    
+    private Node[] fields;
+    private Label tmplabel;
+    private int tmpindex;
+	
+    private boolean tabular = false;
+    private boolean publicPane = false;
+    
+    private PropertyName id = null;
+    private Container node;
+	private Mark temporaryFocus = null;
+
+	public PropertyDetail(Property property, boolean tabular, boolean publicPane, PropertyName id, Container node) {
+		this.tabular = tabular;
+		this.publicPane = publicPane;
+		
+		this.node = node;
+		this.id = id;
+		label = new Label(tabular ? "" : property.getName() + ":");
+		label.setContentDisplay(ContentDisplay.LEFT);
+			
+		if(property instanceof FlexibleListProperty) {
+			properties = ((FlexibleListProperty)property).flatten();
+						
+           	for(Property prop: properties) {
+           		valueLabel.getChildren().add(new Label());
+           		serializers.add(new SimpleSerializer(prop));
+           	}			
+		} else {
+			valueLabel.getChildren().add(new Label());
+			properties = new ArrayList<>();
+			properties.add(property);
+			serializers.add(new SimpleSerializer(property));
+		}
+		
+        // TODO
+        editionType = serializers.get(0).getEditionType();
+
+        // TODO
+        Object val = properties.get(0).getValue();
+        if(val instanceof RefX) {
+        	setValidItems(RefX.values());
+        } else if(val instanceof RefY) {
+        	setValidItems(RefY.values());
+        } else if(val instanceof YSticky) {
+        	setValidItems(YSticky.values());
+        } else if(val instanceof XSticky) {
+        	setValidItems(XSticky.values());
+        }  else if(val instanceof Constraint) {
+        	setValidItems(Constraint.values());
+        } else if(val instanceof ShapeProperty.Type) {
+        	setValidItems(ShapeProperty.Type.values());
+        } else if(val instanceof LineTypeProperty.Type) {
+        	setValidItems(LineTypeProperty.Type.values());
+        } else if(val instanceof ColoringSchemeProperty.Scheme) {
+        	setValidItems(ColoringSchemeProperty.Scheme.values());
+        } else if(properties.get(0) instanceof OpacityProperty) {
+        	setMinMax(0, 1);
+        } else if(properties.get(0) instanceof RotationProperty) {
+        	setMinMax(0, 360);
+        } else if(properties.get(0) instanceof StrokeWidthProperty) {
+        	setMinMax(0, 8);
+        }
+         
+        updateLabels();
+        initInteractors();
+        
+        if(property instanceof Shareable) {
+			label.setDisable(!((Shareable)property).getActiveProperty().getValue());
+			valueLabel.setDisable(!((Shareable)property).getActiveProperty().getValue());
+        	
+        	((Shareable)property).getActiveProperty().addListener(new InvalidationListener() {
+				@Override
+				public void invalidated(Observable observable) {
+					label.setDisable(!((Shareable)property).getActiveProperty().getValue());
+					valueLabel.setDisable(!((Shareable)property).getActiveProperty().getValue());
+				}
+			});
+        }  
+        
+        if(publicPane) {
+        //	label.setStyle("-fx-text-fill: #FF8C00;");
+        }
+        
+        
+	}
+	
+	public PropertyDetail(Property property, boolean tabular, PropertyName id, Container node) {	
+		this(property, tabular, false, id, node);
+	}
+    	
+	public PropertyDetail(Property property, PropertyName id, Container node) {	
+		this(property, false, false, id, node);
+	}
+	
+	
+	void updateLabel(Label label, Property property) {
+		final Node graphic;
+      
+        if(editionType == EditionType.COLOR_PICKER) {
+        	graphic = new Rectangle(20, 10);
+        	((Rectangle)graphic).setFill((Color)property.getValue());
+        	
+        	property.addListener(new ChangeListener<Color>() {
+				@Override
+				public void changed(ObservableValue<? extends Color> observable, Color oldValue, Color newValue) {
+					((Rectangle)graphic).setFill(newValue);
+				}
+			});
+        } else if(property instanceof ShapeProperty) {
+        	graphic = new ImageView(DisplayUtils.getIcon(property.getValue().toString()));
+        	property.addListener(new ChangeListener<ShapeProperty.Type>() {
+				@Override
+				public void changed(ObservableValue<? extends ShapeProperty.Type> observable, ShapeProperty.Type oldValue, ShapeProperty.Type newValue) {
+					((ImageView)graphic).setImage(DisplayUtils.getIcon(property.getValue().toString()));
+				}
+			});
+        } else if(property instanceof LineTypeProperty) {
+        	graphic = new ImageView(DisplayUtils.getIcon(property.getValue().toString()));
+        	property.addListener(new ChangeListener<LineTypeProperty.Type>() {
+				@Override
+				public void changed(ObservableValue<? extends LineTypeProperty.Type> observable, LineTypeProperty.Type oldValue, LineTypeProperty.Type newValue) {
+					((ImageView)graphic).setImage(DisplayUtils.getIcon(property.getValue().toString()));
+					
+					Object owner = property.getBean();
+					// TODO: Need to update the inspector!!!!!
+					if(owner instanceof VisCollection) {
+						((VisFrame)((VisCollection)owner).getRoot()).getInspector().updateTreeViewLabel((VisCollection)owner);
+					}					
+				}
+			});
+        } 
+        else graphic = null;
+        
+        /// TODO: This has changed recently. It's hopefully correct!!!!
+        StringConverter converter = null;
+        if(property.getValue() instanceof Color)
+        	converter = new ColorStringConverter();
+        else if(property.getValue() instanceof RefX)
+        	converter = new RefXStringConverter();
+        else if(property.getValue() instanceof RefY)
+        	converter = new RefYStringConverter();
+        else if(property.getValue() instanceof YSticky)
+        	converter = new XAlignmentStringConverter();
+        else if(property.getValue() instanceof XSticky)
+        	converter = new YAlignmentStringConverter();
+        else if(property.getValue() instanceof Constraint)
+        	converter = new DistributionStringConverter();
+        else if(property instanceof FlexibleListProperty) // TODO: Here, I need to take care of multiple value labels
+        	converter = new ListStringConverter();
+        else if(property instanceof ShapeProperty)
+        	converter = new ShapeStringConverter();
+        else if(property instanceof LineTypeProperty)
+        	converter = new LineTypeStringConverter();
+        else if(property instanceof StrokeWidthProperty || property instanceof OpacityProperty)
+        	converter = new DoubleStringConverter(true);
+        else if(property instanceof ColoringSchemeProperty)
+        	converter = new ColoringStringConverter();
+        else if(property instanceof StringProperty)
+        	converter = null;
+        else converter = new DoubleStringConverter();
+        
+        if(graphic == null) {
+        	// TODO: This needs to change completely!!!
+            if(property instanceof FlexibleListProperty) label.textProperty().bind(new StringBinding() {
+    			@Override
+    			protected String computeValue() {
+    				FlexibleListProperty list = (FlexibleListProperty)property;
+    				return list.getValueAsString();
+    			}
+    		});
+            else if(converter!= null) Bindings.bindBidirectional(label.textProperty(), property, converter); // TODO: This to change as well
+            else label.textProperty().bind(property); 
+        } else { // TODO: ... 
+        	label.setGraphic(graphic);
+        	label.setGraphicTextGap(1.5);
+        }
+                
+        // Change that for tabular data
+        if(tabular) label.setContentDisplay(ContentDisplay.RIGHT);  // TODO: ...   
+	}
+		
+	void updateLabels() {
+		for(int i = 0; i < properties.size(); ++i) {
+			Node child = valueLabel.getChildren().get(i);
+			if(child instanceof Label) updateLabel((Label)valueLabel.getChildren().get(i), properties.get(i));
+		}
+	}
+	
+	private void initInteractors() {
+		fields = new Node[properties.size()];
+		
+		for(int i = 0; i < properties.size(); ++i) {
+			initInteractor(i, (Label)valueLabel.getChildren().get(i), properties.get(i), serializers.get(i));
+		}
+	}
+	
+	// TODO: .....
+	public void createLockIcon(boolean lock, boolean top) {
+		lockIcon = new Label(" ");
+		graphic_unlock = new Label("\u29BB"); //ImageView(DisplayUtils.getIcon("unlinked"));
+		graphic_lock = top ? new Label("\u27F8") : new Label("\u27F9"); //ImageView(DisplayUtils.getIcon("linked"));
+		lockIcon.setGraphic(lock ? graphic_lock : graphic_unlock);
+		lockIcon.setGraphicTextGap(top ? 4.5 : 0);
+	}
+	
+	public void createExpandIcon(boolean expand) {
+		lockIcon = new Label();
+		graphic_unlock = new Label("-");
+		graphic_lock = new Label("+");
+		lockIcon.setGraphic(expand ? graphic_lock : graphic_unlock);
+		lockIcon.setGraphicTextGap(1.5);
+	}
+	
+
+	public void switchLock(boolean lock) {
+		lockIcon.setGraphic(lock ? graphic_lock : graphic_unlock);
+	}
+	
+	private void addGroupSharingInteractor(Label label, Property property, Mark mark) {
+		TooltipCreator.createTooltip(label, property.getName() +  ": Press Shift to Change Visibility"); 
+		
+		BooleanProperty publicProp = ((Shareable)property).getPublicProperty();
+		
+		decorateLabel(label, publicProp.get());
+				
+		label.setOnMouseMoved(new EventHandler<MouseEvent>(){
+		      @Override  
+		      public void handle(MouseEvent event) {
+		    	 label.getScene().getWindow().requestFocus();
+		    	 label.requestFocus();
+		      }
+		}); 
+		label.setOnMouseExited(new EventHandler<MouseEvent>(){
+		      @Override  
+		      public void handle(MouseEvent event) {
+		    	  label.getParent().requestFocus();
+		    	  //label.setStyle("-fx-border-color: none;");
+		      }
+		}); 
+        label.setOnKeyPressed(new EventHandler<KeyEvent>() {
+					@Override
+					public void handle(KeyEvent event) {
+						if(event.isShiftDown()) {
+							publicProp.set(!publicProp.get());
+							
+							Object owner = property.getBean();
+							
+							// TODO: Need to update the inspector!!!!!
+							if(owner instanceof Mark) {
+								VisBody virtualGroup = ((Mark)owner).getRootVirtualGroup();
+								
+								if(virtualGroup instanceof VisCollection) {
+									((VisFrame)virtualGroup.getContainer()).getInspector().updateCollectionViews((VisCollection)virtualGroup);
+								}
+							}
+							
+							//label.setStyle(publicProp.get() ? "-fx-border-color: orange;" : "-fx-border-color: none;");
+						}
+					}
+		});
+        
+        publicProp.addListener(new ChangeListener<Boolean>() {
+			@Override
+			public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+				//label.setStyle(publicProp.get() ? "-fx-border-color: #FF8C00;" : "-fx-border-color: none;");
+				
+				decorateLabel(label, publicProp.get());
+				//VisGroup topGroup = ((VisGroup)mark.getContainer()).getTopGroup();
+				//ArrayList<Property> bindingsgroup = topGroup.getChildPropertyStructure().getBindingsOf(property);
+				
+			}
+		});
+        
+	}
+	
+	private void decorateLabel(Label label, boolean flag) {
+		if(!label.getText().isEmpty()) label.setUnderline(flag);
+		else label.setStyle(flag ? "-fx-border-color: darkgrey; -fx-border-width:1.5px;" : "-fx-border-color: none;");
+
+	}
+	
+	
+	private void initInteractor(int num, Label label, Property property, SimpleSerializer serializer) {				
+		Object bean = property.getBean();
+		if(!publicPane && bean instanceof Mark && property instanceof Shareable && !(node instanceof VisCollection) &&
+				(bean instanceof VisGroup || ((Mark)bean).getContainer() instanceof VisGroup)){
+			addGroupSharingInteractor(label, property, (Mark)bean);
+		}
+			
+        final Control control;
+        switch (editionType) {
+			case COMBO: {
+	        	control = new ComboBox<Object>();
+	        	control.getStyleClass().add("detail-field");
+	        	((ComboBox<Object>)control).getSelectionModel().selectedItemProperty().addListener((o, oldValue, newValue) -> {
+	        		if (newValue != null && !newValue.equals(property.getValue())) {
+	        			serializer.setValue(newValue.toString());
+	        			//updateLabel();
+	        			recover();
+	        		}
+	        	});
+	
+	        	control.setOnMouseClicked(ev -> {
+	        		if (ev.isSecondaryButtonDown()) {
+	        			recover();
+	        		}
+	        	});
+	     	
+	        	break;
+			}
+	        case SLIDER: {
+	        	control = new Slider();
+	        	control.getStyleClass().add("detail-field");
+	        	((Slider)control).valueProperty().addListener((o, oldValue, newValue) -> {
+	        		serializer.setValue(newValue.toString());
+	        		//updateLabel();
+	        	});
+		        	
+	        	break;
+	        }
+	        case COLOR_PICKER: {
+	        	control = new ColorPicker();
+	        	control.getStyleClass().add("detail-field");
+	        	((ColorPicker)control).valueProperty().addListener((o, oldValue, newValue) -> {
+	        		serializer.setValue(newValue.toString());
+	        		///updateLabels();
+	        	});
+	        	
+	        	break;
+	        }
+	        default: {	        	
+	        	control = new TextField(); // TODO: Enable a drag-based text-field modifier....
+	        		        	
+	        	control.setPrefWidth(50);
+	        	control.getStyleClass().add("detail-field");
+	      	
+	        	((TextField)control).setOnAction(ev -> {
+	        		if (serializer != null) {
+	        			serializer.setValue(((TextField)control).getText());
+	        		}
+	
+	        		//updateLabel();
+	        		recover();
+	        	});
+	        }
+		}
+        
+    	PropertyDetail.this.fields[num] = control;
+    	
+    	 	
+    	label.setOnMouseClicked(event -> { // TODO: ... 
+    		
+    		Object container = property.getBean();
+    		if(container != null && container instanceof Mark && !((Mark)container).isHighlighted()) {
+       			temporaryFocus  = ((Mark)container);
+       			temporaryFocus.setHighlight(true, true);
+    		}
+    		
+            if (BasePropertiesPane.activeDetail != null) {
+                BasePropertiesPane.activeDetail.recover();
+            }
+            
+            switch (editionType) {
+	            case COMBO: {
+	            	((ComboBox<Object>)control).setItems(FXCollections.observableArrayList(validItems));
+	            	((ComboBox<Object>)control).getSelectionModel().select(property.getValue());
+	            	break;
+	            }
+	            case SLIDER: {
+	            	((Slider)control).setMax(max);
+	            	((Slider)control).setMin(min);
+	            	((Slider)control).setValue((double)property.getValue());
+	            	break;
+	            }
+	            case COLOR_PICKER: {
+	            	((ColorPicker)control).setValue((Color)property.getValue());
+	            	break;
+	            }
+	            default: {
+	            	((TextField)control).setText(property.getValue() +"");
+	            	break;
+	            }	
+            }
+            
+          //  final HBox group = (HBox) label.getParent(); // TODO: Needs to change or not? Possibly not...
+           // group.getChildren().clear();
+           // group.getChildren().add(PropertyDetail.this.field);
+            
+            valueLabel.getChildren().remove(num);
+            valueLabel.getChildren().add(num, PropertyDetail.this.fields[num]);
+            
+            PropertyDetail.this.fields[num].requestFocus();
+            PropertyDetail.this.tmplabel = label;
+            PropertyDetail.this.tmpindex = num;
+            BasePropertiesPane.activeDetail = PropertyDetail.this;
+            
+            
+           // addTooltip(control, property.getName());
+            
+                    
+        });
+	}
+	
+	public void recover() {
+		if(tmplabel != null) {
+			valueLabel.getChildren().remove(tmpindex);
+			valueLabel.getChildren().add(tmpindex, tmplabel);
+			tmplabel = null;
+		}
+        
+		if(temporaryFocus != null && temporaryFocus.isHighlighted()) {
+			temporaryFocus.setHighlight(false, true);
+			temporaryFocus = null;
+		}
+		
+        BasePropertiesPane.activeDetail = null;
+	}
+	
+    public void setValidItems(final Object[] validItems) {
+        this.validItems = validItems;
+    }
+        
+    public void setMinMax(final double min, final double max) {
+        this.min = min;
+        this.max = max;
+    }
+    
+    public void refresh() {        
+    	updateLabels(); 
+        
+    	serializers.clear();
+       	for(Property prop: properties) {
+       		serializers.add(new SimpleSerializer(prop));
+       	}		
+        
+    }
+
+	@Override
+	public Node getNode() {
+		return label;
+	}
+	
+	@Override
+	public Type getType() {
+		if(!(node instanceof VisBody) || !getGroup().getChildPropertyStructure().getProperties().containsKey(new PropertyName(properties.get(0).getName())))
+			return Type.Value;
+		return Type.Column;
+	}
+
+	
+	@Override
+	public int getColumnsNum() {
+		return properties.size();
+	}
+
+	@Override
+	public int getRowsNum() {
+		if(getType() == Type.Value) return 2;
+		else return ((VisBody)node).getComponents().size() + 1;
+	}
+
+	@Override
+	public Object getPropertiesContent() { // TODO!!!! This need to change to deal with multiple columns!!!!!
+		return FlexibleListProperty.createList(properties.get(0).getBean(), properties);
+	}
+
+	@Override
+	public void update() {
+		// TODO Auto-generated method stub
+		updateLabels();
+	}
+
+	@Override
+	public PropertyName getID() {
+		return id;
+	}
+
+	@Override
+	public VisBody getTopGroup() {
+		return node.getRootVirtualGroup();
+	}
+
+	@Override
+	public VisBody getGroup() {
+		return node.getVirtualGroup();
+	}
+	
+	@Override
+	public Container getContainer() {
+		return node;
+	}
+
+	@Override
+	public boolean isInWide() {
+		return true;
+	}
+	
+	@Override
+	public boolean isNetwork() {
+		return false;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/PropertyDetailColumn.java b/src/fr/inria/structgraphics/ui/inspector/PropertyDetailColumn.java
new file mode 100644
index 0000000000000000000000000000000000000000..6eb37223411f96c04f828a1f30de69c51f67eb7d
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/PropertyDetailColumn.java
@@ -0,0 +1,111 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.ArrayList;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.Draggable;
+import javafx.beans.property.ListProperty;
+import javafx.beans.property.Property;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+
+public class PropertyDetailColumn extends ArrayList<PropertyDetail> implements Draggable {
+	
+	protected FlexibleListProperty propList;
+	protected Node handle;
+	protected PropertyName col;
+	protected PropertiesTable table;
+	
+	private Container node;
+	
+	public PropertyDetailColumn(PropertiesTable table, FlexibleListProperty properties, PropertyName col, Container node) {
+		this.propList = properties;
+		this.col = col;
+		this.table = table;
+		
+		this.node = node;
+	}
+			
+	public void add(ListProperty<Property> properties) {
+		for(Property property: properties) { 
+			if(property != null) add(new PropertyDetail(property, true, col, node));
+		}
+	}
+	
+	public String getName() {
+		//return propList.getName();
+		return col.toString();
+	}
+
+	@Override
+	public Node getNode() {
+		return handle;
+	}
+
+	@Override
+	public Type getType() {
+		return Type.Column;
+	}
+
+	@Override
+	public Object getPropertiesContent() {
+		return table.getProperties(col);
+	}
+
+	@Override
+	public int getColumnsNum() {
+		int length = 1;
+		for(PropertyDetail detail:this)
+			length = Math.max(length, detail.getColumnsNum());
+		
+		return length;
+	}
+
+	@Override
+	public int getRowsNum() {
+		return size() + 1;
+	}
+
+	@Override
+	public void update() {
+		for(PropertyDetail detail:this)
+			detail.updateLabels();
+	}
+
+	public void setHandle(Label label) {
+		this.handle = label;
+	}
+
+	@Override
+	public PropertyName getID() {
+		return col;
+	}
+
+	@Override
+	public VisBody getTopGroup() {
+		return node.getRootVirtualGroup();
+	}
+
+	@Override
+	public VisBody getGroup() {
+		return node.getVirtualGroup();
+	}
+	
+	@Override
+	public Container getContainer() {
+		return node;
+	}
+
+	@Override
+	public boolean isInWide() {
+		return table.isInWide();
+	}
+	
+	@Override
+	public boolean isNetwork() {
+		return table.isNetwork();
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/RefXStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/RefXStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..795dd2549ab7ed5975f984be179b360d4ef3cbae
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/RefXStringConverter.java
@@ -0,0 +1,14 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+
+public class RefXStringConverter extends GeneralStringConverter {
+
+	@Override
+	public Object fromString(String string) {
+		if(string.equalsIgnoreCase("right")) return RefX.Right;
+		else if(string.equalsIgnoreCase("center")) return RefX.Center;
+		else return RefX.Left;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/RefYStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/RefYStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b5f7ff85ea7f8fe6d83c76c80186bc5fcf5a322
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/RefYStringConverter.java
@@ -0,0 +1,14 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+
+public class RefYStringConverter extends GeneralStringConverter {
+
+	@Override
+	public Object fromString(String string) {
+		if(string.equalsIgnoreCase("top")) return RefY.Top;
+		else if(string.equalsIgnoreCase("center")) return RefY.Center;
+		else return RefY.Bottom;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/ShapeStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/ShapeStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..f188d2764793cd535afd8b562f7ff77b32a0d325
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/ShapeStringConverter.java
@@ -0,0 +1,14 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.types.ShapeProperty.Type;
+
+public class ShapeStringConverter extends GeneralStringConverter {
+
+	@Override
+	public Object fromString(String string) {
+		if(string.equalsIgnoreCase("triangle")) return Type.Triangle;
+		else if(string.equalsIgnoreCase("ellipse")) return Type.Ellipse;
+		else return Type.Rectangle;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/SyntaxTab.java b/src/fr/inria/structgraphics/ui/inspector/SyntaxTab.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2137d527cddff677f7ae170df03c1617ad02017
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/SyntaxTab.java
@@ -0,0 +1,61 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.graphics.Container;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TextArea;
+import javafx.scene.layout.VBox;
+
+public class SyntaxTab extends Tab {
+	
+	public static final String TAB_NAME = "Syntax";
+	private InspectorView inspector;
+	
+	private Container activeNode = null;
+	        
+    private VBox vbox;
+    private TextArea textArea;
+
+	public SyntaxTab(InspectorView inspector) {
+		super(TAB_NAME);
+			
+		this.inspector = inspector;
+		
+       // ScrollPane scrollPane = new ScrollPane();
+       // scrollPane.setFitToWidth(true);
+        
+        textArea = new TextArea();
+        textArea.prefRowCountProperty().set(100);
+        textArea.setEditable(false);
+        
+ //       vbox = new VBox();
+ //       vbox.getChildren().add(textArea);
+ //       vbox.setFillWidth(true);
+        //scrollPane.setContent(textArea);
+        
+        setContent(textArea);
+        setClosable(false);
+	}
+	
+
+	public void setActiveNode(Container node) { // TODO: ...
+		if(activeNode == node) return;
+		else clean();
+				
+	}
+		
+	
+    private void createPane(Container node) {
+
+    }
+	
+	
+	private void clean() {
+		vbox.getChildren().clear();
+	}
+	
+	public void cleanAll() {
+		vbox.getChildren().clear();
+	}	    
+    
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/TabularPropertiesGrid.java b/src/fr/inria/structgraphics/ui/inspector/TabularPropertiesGrid.java
new file mode 100644
index 0000000000000000000000000000000000000000..14eb5dac158e7696e0492597cf7ea7d8f2323dcf
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/TabularPropertiesGrid.java
@@ -0,0 +1,85 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.ui.DragManager;
+import javafx.geometry.HPos;
+import javafx.geometry.VPos;
+import javafx.scene.Group;
+import javafx.scene.control.Label;
+import javafx.scene.layout.GridPane;
+
+
+public class TabularPropertiesGrid extends GridPane {
+	
+    static final String DETAIL_LABEL_STYLE = "detail-label";
+        
+    private PropertiesTable table;
+        
+    public TabularPropertiesGrid(boolean nested) {
+       if(nested) getStyleClass().add("nested-detail-pane");
+      //  getStyleClass().add("detail-grid");
+    	        
+        setOnMousePressed(event -> {
+           if(BasePropertiesPane.activeDetail != null) BasePropertiesPane.activeDetail.recover();
+        });
+        
+        setHgap(10);
+        setVgap(2);
+        setSnapToPixel(true);        
+    }
+    
+    protected void addPropertiesTable(PropertiesTable table) {
+    	this.table = table;
+  
+    	table.setHandle(this);
+    	DragManager.getSingleton().observe(table);
+
+    	refreshGrid();
+    }
+    
+    public PropertiesTable getTable() {
+    	return table;
+    }
+    
+    
+    public void refreshGrid() {
+    	getChildren().clear();
+    	
+    	int j = 1;
+    	for(PropertyDetailColumn column: table) {
+    		int i = 0;
+
+    		final Label label = new Label(column.getName()); // I probably need to add some listeners here!!!
+    		column.setHandle(label);
+    		DragManager.getSingleton().observe(column);
+    		
+    		label.getStyleClass().add("detail-label");
+    		GridPane.setHalignment(label, HPos.CENTER);
+       		GridPane.setValignment(label, VPos.TOP);
+       		add(label, j, i++);
+    		
+    		for(PropertyDetail detail: column) {
+    			detail.valueLabel.getStyleClass().add("detail-value");
+    			final Group group = new Group(detail.valueLabel);
+    	        GridPane.setHalignment(group, HPos.RIGHT);
+    			add(group, j, i++);
+    		}
+    		j++;
+    	}
+    }
+    
+    
+    protected void clearPane() {
+        getChildren().clear();
+        //details.clear();
+        // TODO....
+    }
+    
+    public void refresh() {
+    	/*
+        for (int i = 0; i < details.size(); i++) {
+            details.get(i).refresh();           
+        }*/
+    }
+
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/TitledIndividualPropertiesPane.java b/src/fr/inria/structgraphics/ui/inspector/TitledIndividualPropertiesPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..9da7e5ec499207ea8ff027de3f9decce4583784f
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/TitledIndividualPropertiesPane.java
@@ -0,0 +1,56 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.SortedSet;
+
+import fr.inria.structgraphics.types.PropertyName;
+import javafx.beans.property.Property;
+import javafx.scene.Node;
+import javafx.scene.control.TitledPane;
+
+
+public class TitledIndividualPropertiesPane extends TitledPane {
+	
+    static final String DETAIL_LABEL_STYLE = "detail-label";
+    private IndividualPropertiesGrid gridPane;
+    
+    public TitledIndividualPropertiesPane(String name, IndividualPropertiesGrid gridPane) {
+    	super(name, null);
+
+        this.gridPane = gridPane;
+        
+        setOnMousePressed(event -> {
+           if(BasePropertiesPane.activeDetail != null) BasePropertiesPane.activeDetail.recover();
+        });
+        
+        gridPane.setHgap(10);
+        gridPane.setVgap(2);
+        gridPane.setSnapToPixel(true);
+                
+        setContent(gridPane);
+        setCollapsible(false);
+    }
+        
+    protected void addToPane(final Node... nodes) {
+        gridPane.addToPane(nodes);
+    }
+    
+    protected void clearPane() {
+    	gridPane.clearPane();
+    }
+
+    public void addDetails(final Collection<Property> properties) {   
+    	gridPane.addDetails(properties);
+    }
+    
+    
+	public void addDetails(final Collection<Property> properties, SortedSet<PropertyName> common) {
+		gridPane.addDetails(properties, common);
+	}
+    
+    public void refresh() {
+    	gridPane.refresh();
+    }
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/TitledTablePane.java b/src/fr/inria/structgraphics/ui/inspector/TitledTablePane.java
new file mode 100644
index 0000000000000000000000000000000000000000..33d1886dd862b0bc878c43f4906bbf5a71addf0b
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/TitledTablePane.java
@@ -0,0 +1,55 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.ui.DragManager;
+import javafx.scene.control.TitledPane;
+
+public class TitledTablePane extends TitledPane {
+	
+    static final String DETAIL_LABEL_STYLE = "detail-label";
+    private TabularPropertiesGrid gridPane;
+    
+    public TitledTablePane(String name, TabularPropertiesGrid gridPane) {
+    	super(name, null);
+
+       getStyleClass().add("titled-table-pane");
+    	
+        this.gridPane = gridPane;
+        
+        setOnMousePressed(event -> {
+           if(BasePropertiesPane.activeDetail != null) BasePropertiesPane.activeDetail.recover();
+        });
+        
+        gridPane.setHgap(10);
+        gridPane.setVgap(2);
+        gridPane.setSnapToPixel(true);
+                
+        setContent(gridPane);
+        setCollapsible(false);
+    }
+    
+    protected void addPropertiesTable(PropertiesTable table) {
+    	gridPane.addPropertiesTable(table);
+    	
+    	table.setHandle(this);
+    	DragManager.getSingleton().observe(table);
+    }
+    
+    public PropertiesTable getTable() {
+    	return gridPane.getTable();
+    }
+    
+    
+    public void refreshGrid() {
+    	gridPane.refreshGrid();
+    }
+    
+    
+    protected void clearPane() {
+    	gridPane.clearPane();
+    }
+    
+    public void refresh() {
+    	gridPane.refresh();
+    }
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/VisualizationNode.java b/src/fr/inria/structgraphics/ui/inspector/VisualizationNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d3db351cec054ff6b63d7e0de56529a0295ff7c
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/VisualizationNode.java
@@ -0,0 +1,48 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.scene.image.Image;
+
+public class VisualizationNode {
+	private Container container;
+	
+	public VisualizationNode(Container container) {
+		this.container = container;
+	}
+	
+	public String toString() {
+		return getName();
+	}
+	
+    public Image getIcon() {
+    	return null;
+    }
+    
+    public Container getNode() {
+    	return container;
+    }
+    
+    public String getName() {
+    	return (container instanceof Mark) ? container.getName() + " " + container.id.get() : container.getName();
+    }
+    
+    public String getType() {
+    	return container.getType();
+    }
+
+	public boolean isVisible() {
+		return true;
+	}
+
+	public boolean isFocused() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		return (obj instanceof VisualizationNode && container == ((VisualizationNode)obj).container);
+	}
+    
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/VisualizationTreeView.java b/src/fr/inria/structgraphics/ui/inspector/VisualizationTreeView.java
new file mode 100644
index 0000000000000000000000000000000000000000..c77aae69a6abd5024c07d12f935498d326048080
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/VisualizationTreeView.java
@@ -0,0 +1,168 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.GroupLayout.SequentialGroup;
+
+import org.matheclipse.core.builtin.function.Set;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.types.ShapeProperty.Type;
+import fr.inria.structgraphics.ui.tools.SelectTool;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.TreeCell;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.scene.image.ImageView;
+
+public class VisualizationTreeView extends TreeView<VisualizationNode> {
+
+	private InspectorView inspector;
+	private Map<Container, TreeItem<VisualizationNode>> map;
+	private SelectTool selectTool;
+	
+	public VisualizationTreeView(InspectorView inspector) {
+		this.inspector = inspector;
+		map = new HashMap<>();
+		 
+		getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+		
+		setCellFactory(node -> new TreeCell<VisualizationNode>() {
+			 @Override public void updateItem(final VisualizationNode item, final boolean empty) {
+				 super.updateItem(item, empty);
+
+				 TreeItem<VisualizationNode> treeItem = getTreeItem();
+				 setGraphic(treeItem == null ? null : treeItem.getGraphic());
+				 setText(item == null ? null : item.toString());
+				 setOpacity(1);
+			 }
+		 });
+		 
+		 getSelectionModel().getSelectedIndices().addListener(new ListChangeListener<Integer>() {
+			@Override
+			public void onChanged(Change<? extends Integer> c) { // TODO: ...
+				ObservableList<TreeItem<VisualizationNode>> selected = getSelectionModel().getSelectedItems();			
+//				TreeItem<VisualizationNode> selected = getSelectionModel().getSelectedItem();
+				
+				if(selected !=null && !selected.isEmpty()) {
+					TreeItem<VisualizationNode> last = selected.get(selected.size() - 1);
+					if(last != null) inspector.getPropertiesTable().setActiveNode(last.getValue().getNode());
+					
+					if(selectTool != null && selected.get(0).getValue() != null) {
+						selectTool.setActive(true);
+						Container node = selected.get(0).getValue().getNode();
+						if(node != null && node instanceof Mark) selectTool.select((Mark)node, this, selected.size() < 2);
+						for(int i = 1; i < selected.size(); ++i) {
+							TreeItem<VisualizationNode> item = selected.get(i);
+							if(item.getValue().getNode() instanceof Mark) selectTool.addSelection((Mark)item.getValue().getNode(), this);
+						}	
+					}
+				} else if(selectTool != null) selectTool.select(null, this);
+			}
+		 });
+		 
+	}
+
+	public void updateLabel(Container container) {
+		TreeItem<VisualizationNode> item = map.get(container);
+		
+		VisualizationNode node = new VisualizationNode(container);
+		item.setValue(node);		
+		item.setGraphic(new ImageView(DisplayUtils.getIcon(node)));
+	}
+	
+	public void update(Container container) { 
+		map.clear();
+		
+		setRoot(parseSubTree(container));		
+		refreshPropertiesTabs(container);
+	}
+		
+	public void updateOrder() {
+		SelectTool tmp = selectTool;
+		selectTool = null; // To not propagate back the chances to the selectTool
+		
+		update(inspector.getVisualizationFrame());
+		getSelectionModel().clearSelection();
+		
+		for(Mark mark: tmp.getSelected()) {
+			getSelectionModel().select(map.get(mark));
+		}	
+		selectTool = tmp;
+	}
+	
+	public void setActiveNodes(ArrayList<Mark> marks) {
+		SelectTool tmp = selectTool;
+		selectTool = null; // To not propagate back the chances to the selectTool
+		
+		getSelectionModel().clearSelection();
+		for(Mark mark: marks) {
+			getSelectionModel().select(map.get(mark));
+		}
+		
+		selectTool = tmp;
+	}
+		
+	public void setActiveNode(Mark mark) {
+		SelectTool tmp = selectTool;
+		selectTool = null; // To not propagate back the chances to the selectTool
+		
+		getSelectionModel().clearSelection();		
+		getSelectionModel().select(map.get(mark));
+		
+		selectTool = tmp;
+	}
+	
+	private void refreshPropertiesTabs(Container parent) {
+		for(Mark mark:parent.getComponents()) {
+			refreshPropertiesTabs(mark);
+		}
+		
+		inspector.generateView(parent);
+	}
+
+	private TreeItem<VisualizationNode> parseSubTree(Container parent) {		
+		VisualizationNode node = new VisualizationNode(parent);
+		TreeItem<VisualizationNode> item = new TreeItem<VisualizationNode>(node, new ImageView(DisplayUtils.getIcon(node)));
+		
+		map.put(parent, item);
+		
+		for(Mark mark:parent.getComponents()) {
+			item.getChildren().add(parseSubTree(mark));
+		}
+		
+		if(parent instanceof ShapeMark) {
+			ShapeMark mark = (ShapeMark)parent;
+			mark.getShapeProperty().addListener(new ChangeListener<ShapeProperty.Type>() {
+				@Override
+				public void changed(ObservableValue<? extends Type> observable, Type oldValue, Type newValue) {
+					item.graphicProperty().set(new ImageView(DisplayUtils.getIcon(item.getValue())));
+					refresh();
+				}
+			});
+		}
+		
+		item.setExpanded(true);
+		
+		return item;
+	}
+
+	public void setSelector(SelectTool selector) {
+		selectTool = selector;
+		
+		ContextMenu contextMenu = new ContextMenu();
+		selectTool.addItems(contextMenu);
+		this.setContextMenu(contextMenu);
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/XAlignmentStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/XAlignmentStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..31bd538af6291b1942f2ea373c628a8dd999342e
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/XAlignmentStringConverter.java
@@ -0,0 +1,13 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.types.AlignmentProperty.YSticky;
+
+public class XAlignmentStringConverter extends GeneralStringConverter {
+
+	@Override
+	public Object fromString(String string) {
+		if(string.equalsIgnoreCase("no")) return YSticky.No;
+		else return YSticky.Yes;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/YAlignmentStringConverter.java b/src/fr/inria/structgraphics/ui/inspector/YAlignmentStringConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..984c3274b9cb0bd56d26384e83eef28b6d2d3bcb
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/YAlignmentStringConverter.java
@@ -0,0 +1,13 @@
+package fr.inria.structgraphics.ui.inspector;
+
+import fr.inria.structgraphics.types.AlignmentProperty.XSticky;
+
+public class YAlignmentStringConverter extends GeneralStringConverter {
+
+	@Override
+	public Object fromString(String string) {
+		if(string.equalsIgnoreCase("no")) return XSticky.No;
+		else return XSticky.Yes;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/detailmodel/SimpleSerializer.java b/src/fr/inria/structgraphics/ui/inspector/detailmodel/SimpleSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..9629ccdb8719e83e15da1f5b6e802b20336b7181
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/detailmodel/SimpleSerializer.java
@@ -0,0 +1,182 @@
+/*
+ * Scenic View, 
+ * Copyright (C) 2012 Jonathan Giles, Ander Ruiz, Amy Fowler 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package fr.inria.structgraphics.ui.inspector.detailmodel;
+
+import java.lang.reflect.Method;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.ColoringSchemeProperty;
+import fr.inria.structgraphics.types.ConstrainedDoubleProperty;
+import fr.inria.structgraphics.types.DistanceProperty;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.LineTypeProperty;
+import fr.inria.structgraphics.types.OpacityProperty;
+import fr.inria.structgraphics.types.RotationProperty;
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.types.StrokeWidthProperty;
+import fr.inria.structgraphics.types.AlignmentProperty.XSticky;
+import fr.inria.structgraphics.types.AlignmentProperty.YSticky;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import fr.inria.structgraphics.ui.inspector.PropertyDetail.EditionType;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.WritableValue;
+import javafx.scene.paint.Color;
+
+@SuppressWarnings("rawtypes")
+public class SimpleSerializer implements WritableValue<String> {
+
+    private final Property property;
+    private Class<? extends Enum> enumClass;
+    private EditionType editionType;
+    /**
+     * This is getting a bit messy, it works for now but...
+     */
+    private double minValue;
+    private double maxValue;
+
+    public SimpleSerializer(final Property property) {
+        this.property = property;
+        if (property.getValue() instanceof RefX || property.getValue() instanceof RefY 
+        		||  property.getValue() instanceof YSticky || property.getValue() instanceof XSticky
+        		|| property.getValue() instanceof Constraint || property.getValue() instanceof ColoringSchemeProperty.Scheme 
+        		||  property.getValue() instanceof ShapeProperty.Type || property.getValue() instanceof LineTypeProperty.Type ) {
+            editionType = EditionType.COMBO;
+        } else if (property.getValue() instanceof Color) {
+            editionType = EditionType.COLOR_PICKER;
+        } else if(property instanceof FlexibleListProperty) {
+        	editionType = EditionType.NONE;
+        } else if(property instanceof OpacityProperty /*|| property instanceof RotationProperty */|| 
+        		property instanceof StrokeWidthProperty) {
+        	editionType = EditionType.SLIDER;
+        }
+        else {
+            editionType = EditionType.TEXT;
+        }
+    }
+
+    public void setEnumClass(final Class<? extends Enum> enumClass) {
+        this.enumClass = enumClass;
+        if (enumClass != null) {
+            editionType = EditionType.COMBO;
+        }
+    }
+
+    public EditionType getEditionType() {
+        return editionType;
+    }
+
+    @Override 
+    public String getValue() {
+        if (property.getValue() != null) {
+            return property.getValue().toString();
+        }
+        return "";
+    }
+
+    public String[] getValidValues() {
+        if (enumClass != null) {
+            try {
+                final Method m = enumClass.getMethod("values");
+                final Object[] values = (Object[]) m.invoke(null, (Object[]) null);
+                final String[] sValues = new String[values.length];
+                for (int i = 0; i < sValues.length; i++) {
+                    sValues[i] = values[i].toString();
+                }
+                return sValues;
+            } catch (final Exception e) {
+                e.printStackTrace();
+                return null;
+            }
+        } else if (property instanceof BooleanProperty) {
+            return new String[] { "true", "false" };
+        }
+        return null;
+    }
+
+    public double getMinValue() {
+        return minValue;
+    }
+
+    public void setMinValue(final double minValue) {
+        this.minValue = minValue;
+        editionType = EditionType.SLIDER;
+    }
+
+    public double getMaxValue() {
+        return maxValue;
+    }
+
+    public void setMaxValue(final double maxValue) {
+        this.maxValue = maxValue;
+        editionType = EditionType.SLIDER;
+    }
+
+    @SuppressWarnings("unchecked") @Override public void setValue(final String value) {    	
+        try {
+            if (property instanceof ConstrainedDoubleProperty) {
+                ((ConstrainedDoubleProperty)property).updateValue(Double.parseDouble(value));   
+            }
+            else if (property instanceof BooleanProperty) {
+                property.setValue(Boolean.parseBoolean(value));
+            } else if (property instanceof IntegerProperty) {
+                property.setValue(Integer.parseInt(value));
+            } else if (property instanceof DoubleProperty) {
+                property.setValue(Double.parseDouble(value));
+            } else if (property instanceof StringProperty) {
+                property.setValue(value);
+            } else if (property instanceof ObjectProperty) {
+            	Object val = property.getValue();
+            	
+                if (enumClass != null) {
+                    final Method m = enumClass.getMethod("valueOf", String.class);
+                    property.setValue(m.invoke(null, value));
+                } else if (val instanceof Color) {
+                    property.setValue(Color.valueOf(value));
+                } else if(val instanceof RefX) {
+                	property.setValue(RefX.valueOf(value));
+                } else if (val instanceof RefY) {
+                	property.setValue(RefY.valueOf(value));
+                } else if(val instanceof YSticky) {
+                	property.setValue(YSticky.valueOf(value));
+                } else if (val instanceof XSticky) {
+                	property.setValue(XSticky.valueOf(value));
+                } else if(val instanceof Constraint) {
+                	property.setValue(Constraint.valueOf(value));
+                }  else if (val instanceof ShapeProperty.Type) {
+                	property.setValue(ShapeProperty.Type.valueOf(value));
+                } else if (val instanceof LineTypeProperty.Type) {
+                	property.setValue(LineTypeProperty.Type.valueOf(value));
+                } else if(val instanceof ColoringSchemeProperty.Scheme) {
+                	property.setValue(ColoringSchemeProperty.Scheme.valueOf(value));
+                }
+                else {
+                    throw new RuntimeException("Property type not supported");
+                }
+            }
+        } catch (final Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Accordion.png b/src/fr/inria/structgraphics/ui/inspector/icons/Accordion.png
new file mode 100644
index 0000000000000000000000000000000000000000..9aebcade82884339fa5714bb3188f46127af92ae
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Accordion.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/AnchorPane.png b/src/fr/inria/structgraphics/ui/inspector/icons/AnchorPane.png
new file mode 100644
index 0000000000000000000000000000000000000000..94877cadc6ce4edd6a28109f81cf6438086b637e
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/AnchorPane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Application.png b/src/fr/inria/structgraphics/ui/inspector/icons/Application.png
new file mode 100644
index 0000000000000000000000000000000000000000..f4712826f37be38ac5fb550e72858a1d2f2636e8
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Application.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Arc.png b/src/fr/inria/structgraphics/ui/inspector/icons/Arc.png
new file mode 100644
index 0000000000000000000000000000000000000000..13327decab2bc9d1182eb34e79e3e7b622add59b
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Arc.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Area.png b/src/fr/inria/structgraphics/ui/inspector/icons/Area.png
new file mode 100644
index 0000000000000000000000000000000000000000..063775ad44976275816e76d04905c8b415e73179
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Area.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/AreaChart.png b/src/fr/inria/structgraphics/ui/inspector/icons/AreaChart.png
new file mode 100644
index 0000000000000000000000000000000000000000..063775ad44976275816e76d04905c8b415e73179
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/AreaChart.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Axis.png b/src/fr/inria/structgraphics/ui/inspector/icons/Axis.png
new file mode 100644
index 0000000000000000000000000000000000000000..645b1ce1703e513b03d6cb090d7ff774456a1168
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Axis.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/BarChart.png b/src/fr/inria/structgraphics/ui/inspector/icons/BarChart.png
new file mode 100644
index 0000000000000000000000000000000000000000..695eda1829142ed0003169c77e2c890fbb2c3ee4
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/BarChart.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/BarChart3D.png b/src/fr/inria/structgraphics/ui/inspector/icons/BarChart3D.png
new file mode 100644
index 0000000000000000000000000000000000000000..ffa7f8f442d682d470d08555bb2f3305f51875df
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/BarChart3D.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/BorderPane.png b/src/fr/inria/structgraphics/ui/inspector/icons/BorderPane.png
new file mode 100644
index 0000000000000000000000000000000000000000..39145ba1016c3db1f0cecd14c4a20c9c762fe6b2
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/BorderPane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/BubbleChart.png b/src/fr/inria/structgraphics/ui/inspector/icons/BubbleChart.png
new file mode 100644
index 0000000000000000000000000000000000000000..98a2631c05d5f206b273951e638d09efbadec623
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/BubbleChart.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Button.png b/src/fr/inria/structgraphics/ui/inspector/icons/Button.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0f390b4e656591375803d1f0d99558612578a4f
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Button.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Canvas.png b/src/fr/inria/structgraphics/ui/inspector/icons/Canvas.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ad18e55a78ce0bfc0b7e962498861bb1b2b7c93
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Canvas.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Chart.png b/src/fr/inria/structgraphics/ui/inspector/icons/Chart.png
new file mode 100644
index 0000000000000000000000000000000000000000..bd710cf94bae639904b3270547f4ff26580401ba
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Chart.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/CheckBox.png b/src/fr/inria/structgraphics/ui/inspector/icons/CheckBox.png
new file mode 100644
index 0000000000000000000000000000000000000000..0377ddbb0e87e29393329e316917314810b49361
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/CheckBox.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/CheckMenuItem.png b/src/fr/inria/structgraphics/ui/inspector/icons/CheckMenuItem.png
new file mode 100644
index 0000000000000000000000000000000000000000..744b8d81013d6e68939af9036b5d779d5b717972
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/CheckMenuItem.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ChoiceBox.png b/src/fr/inria/structgraphics/ui/inspector/icons/ChoiceBox.png
new file mode 100644
index 0000000000000000000000000000000000000000..5348c245037006e61d3cfbb24c1dd6f641387e64
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ChoiceBox.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Circle.png b/src/fr/inria/structgraphics/ui/inspector/icons/Circle.png
new file mode 100644
index 0000000000000000000000000000000000000000..ea211854362d397baba26431a5637c787b187562
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Circle.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ClipView.png b/src/fr/inria/structgraphics/ui/inspector/icons/ClipView.png
new file mode 100644
index 0000000000000000000000000000000000000000..4dc2fbe5b7ee3c8771ce431e52f55cbd77be7fdf
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ClipView.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ClosePath.png b/src/fr/inria/structgraphics/ui/inspector/icons/ClosePath.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c53620f2807494797d66e05793d116d47a55dd9
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ClosePath.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Collection.png b/src/fr/inria/structgraphics/ui/inspector/icons/Collection.png
new file mode 100644
index 0000000000000000000000000000000000000000..695eda1829142ed0003169c77e2c890fbb2c3ee4
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Collection.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ColorPicker.png b/src/fr/inria/structgraphics/ui/inspector/icons/ColorPicker.png
new file mode 100644
index 0000000000000000000000000000000000000000..af2055673b67983f802906867781f4be76049bfc
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ColorPicker.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ComboBox.png b/src/fr/inria/structgraphics/ui/inspector/icons/ComboBox.png
new file mode 100644
index 0000000000000000000000000000000000000000..f71271bbf8db00fd600ae417e842237aa229b1fd
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ComboBox.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ContextMenu.png b/src/fr/inria/structgraphics/ui/inspector/icons/ContextMenu.png
new file mode 100644
index 0000000000000000000000000000000000000000..17d650939d41d18876b95354a7b05924af9b9730
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ContextMenu.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/CubicCurve.png b/src/fr/inria/structgraphics/ui/inspector/icons/CubicCurve.png
new file mode 100644
index 0000000000000000000000000000000000000000..e5b9b3f176482e0825a5fa31b149f33908a64936
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/CubicCurve.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/CustomMenuItem.png b/src/fr/inria/structgraphics/ui/inspector/icons/CustomMenuItem.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a977652d34f240bb7924e78dcb81f7417552051
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/CustomMenuItem.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/CustomNode.png b/src/fr/inria/structgraphics/ui/inspector/icons/CustomNode.png
new file mode 100644
index 0000000000000000000000000000000000000000..01c507417e7b9411aa6d7880910244f19650b653
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/CustomNode.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Ellipse.png b/src/fr/inria/structgraphics/ui/inspector/icons/Ellipse.png
new file mode 100644
index 0000000000000000000000000000000000000000..0a31957464a693337c107cb57915836316416d85
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Ellipse.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/FXDNode.png b/src/fr/inria/structgraphics/ui/inspector/icons/FXDNode.png
new file mode 100644
index 0000000000000000000000000000000000000000..613cc580e7407cf0cef501be4bfe38099f0619e2
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/FXDNode.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/FlowPane.png b/src/fr/inria/structgraphics/ui/inspector/icons/FlowPane.png
new file mode 100644
index 0000000000000000000000000000000000000000..150f7ee89b1d7d0d6de0acabcbd929dfe5346f79
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/FlowPane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Gadget.png b/src/fr/inria/structgraphics/ui/inspector/icons/Gadget.png
new file mode 100644
index 0000000000000000000000000000000000000000..c49432346ccfd70d317b5bb6e27a6d0fdea42e4c
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Gadget.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Graphic.png b/src/fr/inria/structgraphics/ui/inspector/icons/Graphic.png
new file mode 100644
index 0000000000000000000000000000000000000000..6e44e3c7f9266f3603c740125134bc00d4bc65df
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Graphic.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/GridPane.png b/src/fr/inria/structgraphics/ui/inspector/icons/GridPane.png
new file mode 100644
index 0000000000000000000000000000000000000000..9032be1a1f1b369b4dc515f3c2ac84ecbf83a477
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/GridPane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Group.png b/src/fr/inria/structgraphics/ui/inspector/icons/Group.png
new file mode 100644
index 0000000000000000000000000000000000000000..e4d35c23cd170626c88090d7fd1592c64a738f63
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Group.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/HBox.png b/src/fr/inria/structgraphics/ui/inspector/icons/HBox.png
new file mode 100644
index 0000000000000000000000000000000000000000..063090b2a17464867d6ac2d2a3e6a5e507a80288
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/HBox.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/HTMLEditor.png b/src/fr/inria/structgraphics/ui/inspector/icons/HTMLEditor.png
new file mode 100644
index 0000000000000000000000000000000000000000..89a1d73678209f120f9cb03e4fc57fb86159afd8
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/HTMLEditor.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Hyperlink.png b/src/fr/inria/structgraphics/ui/inspector/icons/Hyperlink.png
new file mode 100644
index 0000000000000000000000000000000000000000..2928c034b5c17685035ed291487e50c20a058bd7
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Hyperlink.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ImageView.png b/src/fr/inria/structgraphics/ui/inspector/icons/ImageView.png
new file mode 100644
index 0000000000000000000000000000000000000000..79f440e51e5c0a0a07978608e25e785b525a718c
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ImageView.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Java.png b/src/fr/inria/structgraphics/ui/inspector/icons/Java.png
new file mode 100644
index 0000000000000000000000000000000000000000..4fa8fabaad2c344d893d5ce59cc19d6333e2b304
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Java.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Label.png b/src/fr/inria/structgraphics/ui/inspector/icons/Label.png
new file mode 100644
index 0000000000000000000000000000000000000000..5face408ddb5d0d88f6cee22a76fbb0039f5020a
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Label.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Line.png b/src/fr/inria/structgraphics/ui/inspector/icons/Line.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2cfda1c47aef2d39660af65e00e7d848960c082
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Line.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/LineChart.png b/src/fr/inria/structgraphics/ui/inspector/icons/LineChart.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b5a218fcb8e6d95da3aa14df954cbe2b61e8986
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/LineChart.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ListView.png b/src/fr/inria/structgraphics/ui/inspector/icons/ListView.png
new file mode 100644
index 0000000000000000000000000000000000000000..1879bc6dbcdbaca9ef2d6435bc91f0acea869461
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ListView.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/LockIcon.png b/src/fr/inria/structgraphics/ui/inspector/icons/LockIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..74add8c05d955dce60c822db2fc84c0b0661af07
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/LockIcon.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/MediaView.png b/src/fr/inria/structgraphics/ui/inspector/icons/MediaView.png
new file mode 100644
index 0000000000000000000000000000000000000000..86180bdefc0155bc759a717f0524a2b79d2bf298
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/MediaView.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Menu.png b/src/fr/inria/structgraphics/ui/inspector/icons/Menu.png
new file mode 100644
index 0000000000000000000000000000000000000000..84cfc162de1a39ad9da305c7996010c64bcd841d
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Menu.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/MenuBar.png b/src/fr/inria/structgraphics/ui/inspector/icons/MenuBar.png
new file mode 100644
index 0000000000000000000000000000000000000000..99d6389b795b6a2cb528b05966fbfeede105b5b7
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/MenuBar.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/MenuButton.png b/src/fr/inria/structgraphics/ui/inspector/icons/MenuButton.png
new file mode 100644
index 0000000000000000000000000000000000000000..037973ad4dff8e98c2a4201c7fd6da7aa91426e3
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/MenuButton.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/MenuItem.png b/src/fr/inria/structgraphics/ui/inspector/icons/MenuItem.png
new file mode 100644
index 0000000000000000000000000000000000000000..81246b88ba1c02a3b0b30e00c2b9921f3391d914
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/MenuItem.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/None.png b/src/fr/inria/structgraphics/ui/inspector/icons/None.png
new file mode 100644
index 0000000000000000000000000000000000000000..e0b4b0054f31605eabfe1d4b9cccaa487e4b3402
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/None.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/NumberAxis.png b/src/fr/inria/structgraphics/ui/inspector/icons/NumberAxis.png
new file mode 100644
index 0000000000000000000000000000000000000000..ecb97343eb6de53d8b3f4fc35f468704f01d9b84
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/NumberAxis.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Pane.png b/src/fr/inria/structgraphics/ui/inspector/icons/Pane.png
new file mode 100644
index 0000000000000000000000000000000000000000..a61a33e4d3e978e82beb2422b4ad1bdb143ed473
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Pane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Panel.png b/src/fr/inria/structgraphics/ui/inspector/icons/Panel.png
new file mode 100644
index 0000000000000000000000000000000000000000..8683c4ac6cc1dd81b8e4f50cf75db7c9b3d605f1
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Panel.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/PasswordField.png b/src/fr/inria/structgraphics/ui/inspector/icons/PasswordField.png
new file mode 100644
index 0000000000000000000000000000000000000000..12af54fc000d2911c9879dabea5996ca97138390
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/PasswordField.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Path.png b/src/fr/inria/structgraphics/ui/inspector/icons/Path.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2cfda1c47aef2d39660af65e00e7d848960c082
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Path.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/PieChart.png b/src/fr/inria/structgraphics/ui/inspector/icons/PieChart.png
new file mode 100644
index 0000000000000000000000000000000000000000..43f8fa4e69b7664c9acd43fe6ed8ccb0cfada2ca
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/PieChart.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/PieChart3D.png b/src/fr/inria/structgraphics/ui/inspector/icons/PieChart3D.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9534bac39323c0c291d7a12c86462f1f0323a31
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/PieChart3D.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Polygon.png b/src/fr/inria/structgraphics/ui/inspector/icons/Polygon.png
new file mode 100644
index 0000000000000000000000000000000000000000..f5b8e7973088eeb0093fbb56af472e4084be379f
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Polygon.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Polyline.png b/src/fr/inria/structgraphics/ui/inspector/icons/Polyline.png
new file mode 100644
index 0000000000000000000000000000000000000000..53b26258868417b015ea879d6a9ec52242b72224
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Polyline.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Popup.png b/src/fr/inria/structgraphics/ui/inspector/icons/Popup.png
new file mode 100644
index 0000000000000000000000000000000000000000..e6890205099db9f4a92b9ba7c08d93826be78e51
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Popup.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ProgressBar.png b/src/fr/inria/structgraphics/ui/inspector/icons/ProgressBar.png
new file mode 100644
index 0000000000000000000000000000000000000000..f58030b6c3ef71c623a59862253ac52b250cc16d
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ProgressBar.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ProgressIndicator.png b/src/fr/inria/structgraphics/ui/inspector/icons/ProgressIndicator.png
new file mode 100644
index 0000000000000000000000000000000000000000..7135f5d1a6d5d37c3b87ee5d6781db90f7b52c45
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ProgressIndicator.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/QuadCurve.png b/src/fr/inria/structgraphics/ui/inspector/icons/QuadCurve.png
new file mode 100644
index 0000000000000000000000000000000000000000..47c2a25034a27cb9b051f8f9dfb6bbf2581f5b60
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/QuadCurve.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/RadioButton.png b/src/fr/inria/structgraphics/ui/inspector/icons/RadioButton.png
new file mode 100644
index 0000000000000000000000000000000000000000..305dfcedf442157bb16abb27cabc8e47ac01d56b
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/RadioButton.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/RadioMenuItem.png b/src/fr/inria/structgraphics/ui/inspector/icons/RadioMenuItem.png
new file mode 100644
index 0000000000000000000000000000000000000000..c52ac5230bc4c6634a8ee05d3ff9ebaecb0f0ba8
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/RadioMenuItem.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Rectangle.png b/src/fr/inria/structgraphics/ui/inspector/icons/Rectangle.png
new file mode 100644
index 0000000000000000000000000000000000000000..72abc0e13ae9fbb6c70be6bb9befc4966956bf81
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Rectangle.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Region.png b/src/fr/inria/structgraphics/ui/inspector/icons/Region.png
new file mode 100644
index 0000000000000000000000000000000000000000..3dedee3ab19270ded86fc8a63bc27d6980256a59
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Region.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/SVGPath.png b/src/fr/inria/structgraphics/ui/inspector/icons/SVGPath.png
new file mode 100644
index 0000000000000000000000000000000000000000..e5b9b3f176482e0825a5fa31b149f33908a64936
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/SVGPath.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ScatterChart.png b/src/fr/inria/structgraphics/ui/inspector/icons/ScatterChart.png
new file mode 100644
index 0000000000000000000000000000000000000000..e63c17028db77bc4c032dc32e501902f11efffa2
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ScatterChart.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ScrollBar.png b/src/fr/inria/structgraphics/ui/inspector/icons/ScrollBar.png
new file mode 100644
index 0000000000000000000000000000000000000000..ba460a8d3cefad404b6a806ac5b428a8c4a53952
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ScrollBar.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ScrollPane.png b/src/fr/inria/structgraphics/ui/inspector/icons/ScrollPane.png
new file mode 100644
index 0000000000000000000000000000000000000000..3002d904f425e2102071fafd917b880bc5117074
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ScrollPane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Separator.png b/src/fr/inria/structgraphics/ui/inspector/icons/Separator.png
new file mode 100644
index 0000000000000000000000000000000000000000..c40a87736830d8d10157fab00eaf18802630da7b
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Separator.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/SeparatorMenuItem.png b/src/fr/inria/structgraphics/ui/inspector/icons/SeparatorMenuItem.png
new file mode 100644
index 0000000000000000000000000000000000000000..22d7f1cb18f686576f6f670276a864795e3bd840
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/SeparatorMenuItem.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Slider.png b/src/fr/inria/structgraphics/ui/inspector/icons/Slider.png
new file mode 100644
index 0000000000000000000000000000000000000000..78a2adbb74446d14b3cf08f7a1c7af75ca520c43
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Slider.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/SplitMenuButton.png b/src/fr/inria/structgraphics/ui/inspector/icons/SplitMenuButton.png
new file mode 100644
index 0000000000000000000000000000000000000000..007ec9065f7ff8837f555b6a9719cdcc8c57973d
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/SplitMenuButton.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/SplitPane.png b/src/fr/inria/structgraphics/ui/inspector/icons/SplitPane.png
new file mode 100644
index 0000000000000000000000000000000000000000..b1b38d2aacd8ff601e688fed4575c806762065c9
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/SplitPane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/SplitPane_v.png b/src/fr/inria/structgraphics/ui/inspector/icons/SplitPane_v.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1519a314361225347ca0e476adb53caa746779e
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/SplitPane_v.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/StackPane.png b/src/fr/inria/structgraphics/ui/inspector/icons/StackPane.png
new file mode 100644
index 0000000000000000000000000000000000000000..54a7e25625801bac2474da21f8d77a1a04dd3405
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/StackPane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/StackedAreaChart.png b/src/fr/inria/structgraphics/ui/inspector/icons/StackedAreaChart.png
new file mode 100644
index 0000000000000000000000000000000000000000..ad7c057179e0330e19463195b1da5014a48584fc
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/StackedAreaChart.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/StackedBarChart.png b/src/fr/inria/structgraphics/ui/inspector/icons/StackedBarChart.png
new file mode 100644
index 0000000000000000000000000000000000000000..01ac120109b5a5891c3e8dc257c8de1ac0b862ea
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/StackedBarChart.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Stage.png b/src/fr/inria/structgraphics/ui/inspector/icons/Stage.png
new file mode 100644
index 0000000000000000000000000000000000000000..77f3e892ea2d6b1d5090454f7762744c826d18ce
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Stage.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Straight.png b/src/fr/inria/structgraphics/ui/inspector/icons/Straight.png
new file mode 100644
index 0000000000000000000000000000000000000000..a3246e0e999e204c3d5d13b5c5abf74e547418c9
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Straight.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Tab.png b/src/fr/inria/structgraphics/ui/inspector/icons/Tab.png
new file mode 100644
index 0000000000000000000000000000000000000000..92bb113a5099be28dc3a3a0c97a95005e6921bf8
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Tab.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/TabPane.png b/src/fr/inria/structgraphics/ui/inspector/icons/TabPane.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e56f636bc43af3aeb886177085205f64343c14e
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/TabPane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/TableColumn.png b/src/fr/inria/structgraphics/ui/inspector/icons/TableColumn.png
new file mode 100644
index 0000000000000000000000000000000000000000..ff6ba46f7ba0c13ccd4d0dc392b419320fe98a5a
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/TableColumn.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/TableRow.png b/src/fr/inria/structgraphics/ui/inspector/icons/TableRow.png
new file mode 100644
index 0000000000000000000000000000000000000000..13e10c5d202a7cd1b1e4d40622fe47b08caeec88
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/TableRow.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/TableView.png b/src/fr/inria/structgraphics/ui/inspector/icons/TableView.png
new file mode 100644
index 0000000000000000000000000000000000000000..f09f545deacafee3e0e3eb82faa776b7097693ab
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/TableView.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Text-1.png b/src/fr/inria/structgraphics/ui/inspector/icons/Text-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..69d67fb8c2ca3094278b91b8cc83b17682cdf667
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Text-1.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Text.png b/src/fr/inria/structgraphics/ui/inspector/icons/Text.png
new file mode 100644
index 0000000000000000000000000000000000000000..dba9ab80f7d0163ce555628df3ccdcd15afd1dec
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Text.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/TextArea.png b/src/fr/inria/structgraphics/ui/inspector/icons/TextArea.png
new file mode 100644
index 0000000000000000000000000000000000000000..65b69e2462cfc2c1b97c78040116f87ebcb85a3a
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/TextArea.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/TextField.png b/src/fr/inria/structgraphics/ui/inspector/icons/TextField.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c8420afa58ea735efca5124067bb300b310a3cf
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/TextField.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/TilePane.png b/src/fr/inria/structgraphics/ui/inspector/icons/TilePane.png
new file mode 100644
index 0000000000000000000000000000000000000000..55945b6a34f8b0a5af776a76cee1c4b325123131
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/TilePane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/TitledPane.png b/src/fr/inria/structgraphics/ui/inspector/icons/TitledPane.png
new file mode 100644
index 0000000000000000000000000000000000000000..33a08ecb49b6e7bc7aedb10773ee13ebc97d72f9
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/TitledPane.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ToggleButton.png b/src/fr/inria/structgraphics/ui/inspector/icons/ToggleButton.png
new file mode 100644
index 0000000000000000000000000000000000000000..b91432d492b3fbb229e1743954cbfc565efd0e57
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ToggleButton.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/ToolBar.png b/src/fr/inria/structgraphics/ui/inspector/icons/ToolBar.png
new file mode 100644
index 0000000000000000000000000000000000000000..99f521e9af6d219b5def8a81a46ab64fb3c5ce55
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/ToolBar.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Tooltip.png b/src/fr/inria/structgraphics/ui/inspector/icons/Tooltip.png
new file mode 100644
index 0000000000000000000000000000000000000000..1846d4263ab4e5ba0bb5acc7a061b616e037e512
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Tooltip.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/TopBottom.png b/src/fr/inria/structgraphics/ui/inspector/icons/TopBottom.png
new file mode 100644
index 0000000000000000000000000000000000000000..72ca88f0b7e54c8a58ded206f9c6bad9363f88c4
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/TopBottom.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/TreeView.png b/src/fr/inria/structgraphics/ui/inspector/icons/TreeView.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce599242af40a9a98dcab1cdfe1249685237112f
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/TreeView.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/Triangle.png b/src/fr/inria/structgraphics/ui/inspector/icons/Triangle.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f491c5b3e66af9fdd85b4fd77ac8c28915d6c01
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/Triangle.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/VBox.png b/src/fr/inria/structgraphics/ui/inspector/icons/VBox.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa33845554dc271c9c7325562d42fda41e92c0fa
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/VBox.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/WebView.png b/src/fr/inria/structgraphics/ui/inspector/icons/WebView.png
new file mode 100644
index 0000000000000000000000000000000000000000..57ffb2a0f6eadc5f389ddf73fa1e54f68f93d425
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/WebView.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/bezier.png b/src/fr/inria/structgraphics/ui/inspector/icons/bezier.png
new file mode 100644
index 0000000000000000000000000000000000000000..3d41147b0468f8633ef3afcedfcc6820a485040d
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/bezier.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/bezier_.png b/src/fr/inria/structgraphics/ui/inspector/icons/bezier_.png
new file mode 100644
index 0000000000000000000000000000000000000000..e0b4bf91a33e06365bf9303e8bb5d903a442d281
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/bezier_.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/beziersolid.png b/src/fr/inria/structgraphics/ui/inspector/icons/beziersolid.png
new file mode 100644
index 0000000000000000000000000000000000000000..e5b9b3f176482e0825a5fa31b149f33908a64936
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/beziersolid.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/cleaning.png b/src/fr/inria/structgraphics/ui/inspector/icons/cleaning.png
new file mode 100644
index 0000000000000000000000000000000000000000..0baef1e73c80f9f0d7a5f40beb8acba8f08d07b4
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/cleaning.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/construct-2.png b/src/fr/inria/structgraphics/ui/inspector/icons/construct-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..65dbe5375d0ba76bb0f70538298fcf58e796350b
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/construct-2.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/construct.png b/src/fr/inria/structgraphics/ui/inspector/icons/construct.png
new file mode 100644
index 0000000000000000000000000000000000000000..a1c78a5081846a579722e9e86fa44ea5e35d51e4
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/construct.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/drag.png b/src/fr/inria/structgraphics/ui/inspector/icons/drag.png
new file mode 100644
index 0000000000000000000000000000000000000000..1cee3a97c709958ee726af8fc96943602aac86cd
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/drag.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/editclear.png b/src/fr/inria/structgraphics/ui/inspector/icons/editclear.png
new file mode 100644
index 0000000000000000000000000000000000000000..c09720f04ec6a8cadbb23bf682b72e0a792479e8
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/editclear.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/eraser.png b/src/fr/inria/structgraphics/ui/inspector/icons/eraser.png
new file mode 100644
index 0000000000000000000000000000000000000000..572a0be29068690718e4a15219b8217118588394
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/eraser.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/flow.png b/src/fr/inria/structgraphics/ui/inspector/icons/flow.png
new file mode 100644
index 0000000000000000000000000000000000000000..816e0581fdecc5c83b978c2c75a8a203135fc243
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/flow.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/library-2.png b/src/fr/inria/structgraphics/ui/inspector/icons/library-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..5610cd2ec3cc8bcf2232b852a1bd6086a7ebbcaa
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/library-2.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/library.png b/src/fr/inria/structgraphics/ui/inspector/icons/library.png
new file mode 100644
index 0000000000000000000000000000000000000000..30e8c851d6ce95c2389f52b23979383a2e4aacd7
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/library.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/link.png b/src/fr/inria/structgraphics/ui/inspector/icons/link.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c5dcbb2975b9af4d7a59b4285f6cc893312418f
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/link.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/linked.png b/src/fr/inria/structgraphics/ui/inspector/icons/linked.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e28ac967de8ea1ae98fc5d690656e83bc6706ce
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/linked.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/lock.png b/src/fr/inria/structgraphics/ui/inspector/icons/lock.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd218b1bb773cf0bbaa5f5837bdad66c42b00d88
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/lock.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/mu.png b/src/fr/inria/structgraphics/ui/inspector/icons/mu.png
new file mode 100644
index 0000000000000000000000000000000000000000..ee4fe25303e704a9446291c878b41731dbda1c32
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/mu.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/multiply.png b/src/fr/inria/structgraphics/ui/inspector/icons/multiply.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2bf0cbeabc7bc2e0db5c0f55d1b39c0de2abee6
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/multiply.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/open-file.png b/src/fr/inria/structgraphics/ui/inspector/icons/open-file.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b75dd06f2ae593b4e2f16979000bc487aca66dd
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/open-file.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/open-folder.png b/src/fr/inria/structgraphics/ui/inspector/icons/open-folder.png
new file mode 100644
index 0000000000000000000000000000000000000000..a6ab2f5c9c7439957e25155c946cca5358c44cde
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/open-folder.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/save.png b/src/fr/inria/structgraphics/ui/inspector/icons/save.png
new file mode 100644
index 0000000000000000000000000000000000000000..68dda5a9f099c288bc010b71327e49784609ca2c
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/save.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/select.png b/src/fr/inria/structgraphics/ui/inspector/icons/select.png
new file mode 100644
index 0000000000000000000000000000000000000000..fc378c8c9ae8df3cdb52ec27a56b04dc70e3d4d0
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/select.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/straightsolid.png b/src/fr/inria/structgraphics/ui/inspector/icons/straightsolid.png
new file mode 100644
index 0000000000000000000000000000000000000000..13fce1fb9b83a60fccb5fc63102179b0075796c9
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/straightsolid.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/unlinked.png b/src/fr/inria/structgraphics/ui/inspector/icons/unlinked.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe3ed01559bc0109dd703fd38b7a7ceb581294f2
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/unlinked.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/unlock.png b/src/fr/inria/structgraphics/ui/inspector/icons/unlock.png
new file mode 100644
index 0000000000000000000000000000000000000000..7985379f7b795ba1233fc1b19c81a0ba084bd1da
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/unlock.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/x-center.png b/src/fr/inria/structgraphics/ui/inspector/icons/x-center.png
new file mode 100644
index 0000000000000000000000000000000000000000..910fc9158b179f907c5107ebfd3726f7ef1c4c50
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/x-center.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/x-free.png b/src/fr/inria/structgraphics/ui/inspector/icons/x-free.png
new file mode 100644
index 0000000000000000000000000000000000000000..639caf97b62a10987d7d78601745e559f12b95f7
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/x-free.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/x-left.png b/src/fr/inria/structgraphics/ui/inspector/icons/x-left.png
new file mode 100644
index 0000000000000000000000000000000000000000..99077ca7ad5abc562d27424f7963a1d5969ccdd0
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/x-left.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/x-right.png b/src/fr/inria/structgraphics/ui/inspector/icons/x-right.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a90b48f80bb6c9abb2e1730f8932f05e54de742
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/x-right.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/y-bottom.png b/src/fr/inria/structgraphics/ui/inspector/icons/y-bottom.png
new file mode 100644
index 0000000000000000000000000000000000000000..92e1d84caf8c2f056b3a61ea731079b7e7763834
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/y-bottom.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/y-center.png b/src/fr/inria/structgraphics/ui/inspector/icons/y-center.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f69770e094b45987086f76d56eb4204a9521ce1
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/y-center.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/y-free.png b/src/fr/inria/structgraphics/ui/inspector/icons/y-free.png
new file mode 100644
index 0000000000000000000000000000000000000000..627f4cb0019b81e908dbdb8bbaa1721dba05e21d
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/y-free.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/icons/y-top.png b/src/fr/inria/structgraphics/ui/inspector/icons/y-top.png
new file mode 100644
index 0000000000000000000000000000000000000000..8d97bde1f51581f3e0565b62f7fe9f36beaeb656
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/inspector/icons/y-top.png differ
diff --git a/src/fr/inria/structgraphics/ui/inspector/inspector.css b/src/fr/inria/structgraphics/ui/inspector/inspector.css
new file mode 100644
index 0000000000000000000000000000000000000000..b57f8061c8698ec5254d27ea77b920d2dd62a80c
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/inspector.css
@@ -0,0 +1,169 @@
+/*
+ * Scenic View, 
+ * Copyright (C) 2012 Jonathan Giles, Ander Ruiz, Amy Fowler 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+.split-pane {
+    -fx-background-insets: 0, 1 0 1 0;
+    -fx-padding: 0 0 1 0;
+}
+.split-pane *.split-pane-divider{
+    -fx-padding: 0 1 0 0;
+    -fx-background-color: transparent, -fx-box-border;
+    -fx-background-insets: 0 -3 0 -3, 0;
+    -fx-border-color: null;
+}
+.split-pane *.horizontal-grabber {
+    -fx-padding: 0;
+    -fx-shape: "";
+}
+
+.tree-view {
+    -fx-background-insets: 0, 0 0 -1 0;
+    -fx-background-radius: 0;
+    -fx-padding: 0;
+}
+
+.tree-view:focused .tree-cell:filled:selected {
+    -fx-background-color: #D2B48C; // Focused color
+
+}
+
+.scanning-label {
+    -fx-font-size:12;
+    -fx-font-weight: bold;
+}
+
+.scroll-pane {
+    -fx-padding: 0;
+    -fx-background-insets: 0;
+}
+
+.detail-pane #title-label {
+    -fx-font: bold 12pt System;
+}
+
+.detail-grid {
+    -fx-background-insets: 0,1,2;
+    -fx-background-radius: 0,0,0;
+    -fx-padding: 4 6 6 6;
+    -fx-hgap: 4;
+    -fx-vgap: 1;
+}
+
+.titled-pane > .title {
+    -fx-background-radius: 0, 0, 0;
+    
+}
+.titled-pane > *.content {
+    -fx-background-insets: 0, 0 0 0 0;
+    -fx-padding: 0 0 -1 0;
+}
+
+.detail-pane .detail-dummy {
+    -fx-font-size: 4;
+}
+
+.detail-pane .detail-label {
+    -fx-font-weight: bold;
+    -fx-text-fill: #0082dd;
+}
+
+.detail-pane .updated-detail-label {
+    -fx-font-weight: bold;
+    -fx-text-fill: #FF0000;
+}
+
+.detail-pane .detail-value {
+    -fx-text-fill: black;
+    -fx-font-weight: normal;
+    -fx-font-size: 11;
+}
+
+.detail-pane {
+    -fx-text-fill: black;
+}
+
+.titled-table-pane {  
+	-fx-padding: 10px 0px 0px 0px ;
+}
+
+.nested-detail-pane {
+	-fx-text-fill: #0082dd;   
+	-fx-padding: 6px ;
+}
+
+.detail-field {
+    -fx-text-fill: black;
+    -fx-font-size: 12;
+}
+
+.constraints-display {
+    -fx-padding: 2 2 2 2;
+}
+
+.constraints-display .label.key {
+    -fx-text-fill: #0082dd;
+}
+
+.gridpane-constraint-display {
+    -fx-padding: 2 2 2 2;
+    -fx-background-color: #eeeeee;
+}
+
+.gridpane-constraint-display .label {
+    -fx-text-fill: #0082dd;
+}
+
+
+.search-bar .label {
+    -fx-font-weight: bold;
+}
+
+#main-statusbar {
+    -fx-padding: 3 4 3 4;
+    -fx-spacing: 4;
+}
+#main-statusbar .value-name {
+    -fx-font-weight: bold;
+}
+
+.animations-table-view .table-cell {
+     -fx-alignment: BASELINE_RIGHT;
+ }
+
+
+.tab-pane > .tab-header-area > .tab-header-background {
+    -fx-effect: null;
+}
+/*
+ * For Testing
+ */
+
+.color {
+    -fx-fill: orange;
+}
+#rect4 {
+    -fx-arc-width: 10;
+    -fx-arc-height: 10;
+}
+#First {
+    -fx-font: bold 12pt System;
+    -fx-background-color: red;
+}
+
+
diff --git a/src/fr/inria/structgraphics/ui/inspector/util/PropertyCloner.java b/src/fr/inria/structgraphics/ui/inspector/util/PropertyCloner.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e1e0557e52a9d2314d9667d810d8b2722db4e6e
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/util/PropertyCloner.java
@@ -0,0 +1,90 @@
+package fr.inria.structgraphics.ui.inspector.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.AlignmentXProperty;
+import fr.inria.structgraphics.types.AlignmentYProperty;
+import fr.inria.structgraphics.types.ColorProperty;
+import fr.inria.structgraphics.types.ColoringSchemeProperty;
+import fr.inria.structgraphics.types.ComponentRefXProperty;
+import fr.inria.structgraphics.types.ComponentRefYProperty;
+import fr.inria.structgraphics.types.ContainerRefXProperty;
+import fr.inria.structgraphics.types.ContainerRefYProperty;
+import fr.inria.structgraphics.types.DeltaXProperty;
+import fr.inria.structgraphics.types.DeltaYProperty;
+import fr.inria.structgraphics.types.DistributionProperty;
+import fr.inria.structgraphics.types.DistributionXProperty;
+import fr.inria.structgraphics.types.DistributionYProperty;
+import fr.inria.structgraphics.types.DoubleListProperty;
+import fr.inria.structgraphics.types.FillColorProperty;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.FontSizeProperty;
+import fr.inria.structgraphics.types.HeightProperty;
+import fr.inria.structgraphics.types.LineTypeProperty;
+import fr.inria.structgraphics.types.OpacityProperty;
+import fr.inria.structgraphics.types.RotationProperty;
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.types.Shareable;
+import fr.inria.structgraphics.types.StrokeColorProperty;
+import fr.inria.structgraphics.types.StrokeWidthProperty;
+import fr.inria.structgraphics.types.TextProperty;
+import fr.inria.structgraphics.types.WidthProperty;
+import fr.inria.structgraphics.types.XProperty;
+import fr.inria.structgraphics.types.YProperty;
+import fr.inria.structgraphics.types.AlignmentProperty.XSticky;
+import fr.inria.structgraphics.types.AlignmentProperty.YSticky;
+import fr.inria.structgraphics.types.ColoringSchemeProperty.Scheme;
+import javafx.beans.property.Property;
+import javafx.scene.paint.Color;
+
+public class PropertyCloner {
+
+	public static Property replicate(Property property) {
+		
+		Property prop;
+		
+		if(property instanceof WidthProperty) prop = new WidthProperty(property.getBean(), (double)property.getValue());
+		else if(property instanceof HeightProperty) prop = new HeightProperty(property.getBean(), (double)property.getValue());
+		else if(property instanceof XProperty) prop = new XProperty(property.getBean(), (double)property.getValue());
+		else if(property instanceof YProperty) prop = new YProperty(property.getBean(), (double)property.getValue());
+		else if(property instanceof DeltaXProperty) prop = new DeltaXProperty(property.getBean(), (double)property.getValue());
+		else if(property instanceof DeltaYProperty) prop = new DeltaYProperty(property.getBean(), (double)property.getValue());
+		else if(property instanceof RotationProperty) prop = new RotationProperty(property.getBean(), (double)property.getValue());
+		else if(property instanceof StrokeColorProperty) prop = new StrokeColorProperty(property.getBean(), (Color) property.getValue());
+		else if(property instanceof FillColorProperty) prop = new FillColorProperty(property.getBean(), (Color) property.getValue());
+		else if(property instanceof ContainerRefXProperty) prop = new ContainerRefXProperty(property.getBean(), (RefX) property.getValue());
+		else if(property instanceof ContainerRefYProperty) prop = new ContainerRefYProperty(property.getBean(), (RefY) property.getValue());
+		else if(property instanceof ComponentRefXProperty) prop = new ComponentRefXProperty(property.getBean(), (RefX) property.getValue());
+		else if(property instanceof ComponentRefYProperty) prop = new ComponentRefYProperty(property.getBean(), (RefY) property.getValue());
+		else if(property instanceof StrokeWidthProperty) prop = new StrokeWidthProperty(property.getBean(), (double)property.getValue());
+		else if(property instanceof AlignmentXProperty) prop = new AlignmentXProperty(property.getBean(), (YSticky) property.getValue());
+		else if(property instanceof AlignmentYProperty) prop = new AlignmentYProperty(property.getBean(), (XSticky) property.getValue());
+		else if(property instanceof ShapeProperty) prop = new ShapeProperty(property.getBean(), (ShapeProperty.Type) property.getValue());
+		else if(property instanceof LineTypeProperty) prop = new LineTypeProperty(property.getBean(), (LineTypeProperty.Type) property.getValue());
+		else if(property instanceof DistributionXProperty) prop = new DistributionXProperty(property.getBean(), (DistributionProperty.Constraint) property.getValue());
+		else if(property instanceof DistributionYProperty) prop = new DistributionYProperty(property.getBean(), (DistributionProperty.Constraint) property.getValue());
+		else if(property instanceof TextProperty) prop = new TextProperty(property.getBean(), (String)property.getValue());
+		else if(property instanceof FontSizeProperty) prop = new FontSizeProperty(property.getBean(), (double)property.getValue());
+		else if(property instanceof OpacityProperty) prop = new OpacityProperty(property.getBean(), (double)property.getValue());
+		else if(property instanceof ColoringSchemeProperty) prop = new ColoringSchemeProperty(property.getBean(), (Scheme)property.getValue());
+		else if(property instanceof FlexibleListProperty) {
+			List<Property> list = new ArrayList<>();
+			for(Property prop_: (FlexibleListProperty)property) 
+				list.add(PropertyCloner.replicate(prop_));
+			
+			return FlexibleListProperty.createList(property.getBean(), list);
+		}		
+		else return property;
+		
+		if(property instanceof Shareable) {
+			((Shareable)prop).getActiveProperty().bind(((Shareable) property).getActiveProperty());
+			((Shareable)prop).getPublicProperty().bind(((Shareable) property).getPublicProperty());
+			((Shareable)prop).getHiddenProperty().bind(((Shareable) property).getHiddenProperty());
+		}
+		
+		return prop;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/inspector/util/TooltipCreator.java b/src/fr/inria/structgraphics/ui/inspector/util/TooltipCreator.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6c0223d0b3376652bea45d686e6184bac76399a
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/inspector/util/TooltipCreator.java
@@ -0,0 +1,41 @@
+package fr.inria.structgraphics.ui.inspector.util;
+
+import java.lang.reflect.Field;
+
+import javafx.animation.KeyFrame;
+import javafx.animation.Timeline;
+import javafx.scene.Node;
+import javafx.scene.control.Tooltip;
+import javafx.util.Duration;
+
+public class TooltipCreator {
+
+	private final static Duration duration = new Duration(250);
+	
+	public static Tooltip createTooltip(Node node, String text) {
+		Tooltip t = new Tooltip(text);
+		Tooltip.install(node, t); 
+		
+		return t;
+	}
+	
+	// See: https://stackoverflow.com/questions/26854301/how-to-control-the-javafx-tooltips-delay
+	public static void hackTooltipStartTiming() {
+		Tooltip tooltip = new Tooltip();
+		
+	    try {
+	        Field fieldBehavior = tooltip.getClass().getDeclaredField("BEHAVIOR");
+	        fieldBehavior.setAccessible(true);
+	        Object objBehavior = fieldBehavior.get(tooltip);
+
+	        Field fieldTimer = objBehavior.getClass().getDeclaredField("activationTimer");
+	        fieldTimer.setAccessible(true);
+	        Timeline objTimer = (Timeline) fieldTimer.get(objBehavior);
+
+	        objTimer.getKeyFrames().clear();
+	        objTimer.getKeyFrames().add(new KeyFrame(duration));
+	    } catch (Exception e) {
+	        e.printStackTrace();
+	    }
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/library/LibraryPane.java b/src/fr/inria/structgraphics/ui/library/LibraryPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..ddb8a79575c1dc9883b985398756510620f742ae
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/library/LibraryPane.java
@@ -0,0 +1,238 @@
+package fr.inria.structgraphics.ui.library;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.MarkFactory;
+import fr.inria.structgraphics.graphics.SimpleMark;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.persistence.JsonDescription;
+import fr.inria.structgraphics.persistence.JsonObjectReader;
+import fr.inria.structgraphics.persistence.JsonObjectWriter;
+import fr.inria.structgraphics.ui.DisplayPreferences;
+import fr.inria.structgraphics.ui.viscanvas.Canvas;
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Pos;
+import javafx.scene.Group;
+import javafx.scene.SnapshotParameters;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.DragEvent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.input.TransferMode;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.transform.Transform;
+import javafx.stage.WindowEvent;
+
+public class LibraryPane extends BorderPane {
+
+	public final String DRAG_CODE= "LiBRArY";
+	
+	private ArrayList<Mark> libraryComponents = new ArrayList<>();
+	
+	private VisFrame fakeframe;
+	
+	private CanvasFrame canvasFrame;
+	
+	private VBox items;
+    private Canvas canvas;
+    	
+	public LibraryPane(CanvasFrame canvasFrame) {
+		items = new VBox(0);
+		
+		this.canvasFrame = canvasFrame;
+
+		canvas = new Canvas();
+		canvas.getChildren().add(items);
+		
+		canvas.setStyle("-fx-background-color: #FFFFFF;");
+		items.setStyle("-fx-background-color: #FFFFFF;");
+		
+		fakeframe =  MarkFactory.createVisFrame(DisplayPreferences.CANVAS_WIDTH, DisplayPreferences.CANVAS_HEIGHT);
+		
+		canvasFrame.getCanvas().setOnDragOver(new EventHandler<DragEvent>() { 
+		    public void handle(DragEvent event) {
+		    	Dragboard db = event.getDragboard();
+		    	
+		    	//TODO: I need to fix that so that it only activate when
+		    	SimpleMark mark = canvasFrame.getDragged();
+		        if (mark != null && db.hasString() && db.getString().equals(DRAG_CODE)) {
+		            event.acceptTransferModes(TransferMode.COPY_OR_MOVE);		           		            
+		        }
+	            event.consume();
+		    }
+		});
+				
+		canvasFrame.getCanvas().setOnDragDropped(new EventHandler <DragEvent>() {
+            public void handle(DragEvent event) {
+                Dragboard db = event.getDragboard();
+                boolean success = false;
+                if (db.hasString() && db.getString().equals(DRAG_CODE)) {
+                	addMarkToCanvas(canvasFrame.getDragged(), event.getX(), event.getY());
+                	
+                    success = true;
+                }
+                event.setDropCompleted(success);
+                
+                event.consume();
+            }
+        });
+		
+		//load();
+	}
+	
+	public ArrayList<Mark> getComponents() {
+		return libraryComponents;
+	}
+	
+	private void addMarkToCanvas(SimpleMark mark, double x, double y) {
+		SimpleMark copy = mark.createCopy(canvasFrame.getVisFrame(), 0, 0);
+		copy.initProperties();
+		copy.getCoords().x.set(x);
+		copy.getCoords().y.set(copy.getRootHeight() - y);
+		copy.update();
+		
+		canvasFrame.getInspector().update();
+	}
+	
+	public Canvas getCanvas() {
+		return canvas;
+	}
+		
+	public void addToLibrary(SimpleMark mark) {
+		SimpleMark copy = mark.createCopy(fakeframe, 0, 0);
+		copy.initProperties();
+		copy.update();
+		libraryComponents.add(mark);
+		addToList(copy);
+		
+		save();
+	}
+	
+	private void addToList(SimpleMark mark) {		
+		Group group = mark.getGroup();
+	
+		//double w = group.getBoundsInLocal().getWidth();
+		double scalex = Math.min(1, ( CanvasFrame.LIB_WIDTH - 60) / mark.width());
+		double scaley = Math.min(1, 100/mark.height());
+		double scale = Math.min(scalex, scaley);
+			
+		SnapshotParameters params = new SnapshotParameters();
+		params.setTransform(Transform.scale(scale, scale));
+		
+		ImageView imageView = new ImageView();
+		imageView.setImage(group.snapshot(params, null));
+		
+		HBox hbox = new HBox(0);
+		hbox.setAlignment(Pos.CENTER);
+		//hbox.setPadding(new Insets(10, 10, 10, 10));
+		hbox.setStyle("-fx-padding: 8;" + "-fx-border-style: solid inside;"
+		        + "-fx-border-width: 2;" + "-fx-border-insets: 5;"
+		        + "-fx-border-radius: 5;" + "-fx-border-color: #aaaadd;");
+		
+		hbox.getChildren().add(imageView);
+		
+		items.getChildren().add(hbox);
+		
+        hbox.setOnDragDetected(
+        		new EventHandler<MouseEvent>() { 
+        			public void handle(MouseEvent event) {   		
+		                Dragboard db = imageView.startDragAndDrop(TransferMode.COPY);
+		                ClipboardContent content = new ClipboardContent();
+		                content.putString(DRAG_CODE);
+		                db.setContent(content);
+		                
+		                canvasFrame.setDraggable(mark);
+		                event.consume();
+        			}
+        });
+        
+        hbox.setOnMousePressed(new EventHandler<MouseEvent>() {
+
+			@Override
+			public void handle(MouseEvent event) { 
+				
+				if(event.isSecondaryButtonDown()) {
+					ContextMenu contextMenu = new ContextMenu();
+				  
+			        MenuItem item = new MenuItem("Remove from Library");
+			        item.setOnAction(new EventHandler<ActionEvent>() {
+			            @Override
+			            public void handle(ActionEvent event) {			     
+			            	libraryComponents.remove(items.getChildren().indexOf(hbox));
+			            	items.getChildren().remove(hbox);
+			            	save();
+			            }
+			        });
+			        
+			        contextMenu.getItems().add(item);
+			        
+			        contextMenu.setOnHiding(new EventHandler<WindowEvent>() {
+						@Override
+						public void handle(WindowEvent event) {
+							canvasFrame.getSplitPane().setContextMenu(null);
+						}
+					});
+			        
+			        canvasFrame.getSplitPane().setContextMenu(contextMenu);
+			}
+		}
+      });
+	}
+
+	public void clear() {
+		items.getChildren().clear();
+	}
+	
+	public void load() { 
+		File libfile = new File("./sessions/library.json");
+		if(libfile == null) return;
+
+		JsonArray visArray;
+		JsonDescription descr = new JsonDescription(libfile);
+		visArray = descr.isLibrary() ? descr.getLibraryArray(false) : descr.getVisArray(false);		
+		load(visArray);
+	}
+	
+	public void load(JsonArray visArray) { 		
+		if(visArray != null && !visArray.isEmpty())
+			libraryComponents = JsonObjectReader.readChildrenFromJasonArray(fakeframe, visArray);
+				
+		for(Mark mark:libraryComponents) {
+			addToList((SimpleMark)mark);
+		}
+	}
+	
+	public void save() {
+		if(libraryComponents.isEmpty()) return;
+		
+		File libfile = new File("./sessions/library.json");
+		if(libfile == null) return;
+		else {
+			JsonObject visualizations = 
+					JsonObjectWriter.saveToJason(libraryComponents, true);
+			try {
+				FileWriter writer = new FileWriter(libfile, false);
+				writer.write(JsonObjectWriter.fromObjectToReadableString(visualizations, 0).toString());
+				writer.close();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/AreaContent.java b/src/fr/inria/structgraphics/ui/spreadsheet/AreaContent.java
new file mode 100644
index 0000000000000000000000000000000000000000..b979e31a360883f0e6fd19d3b6c3d064b0b75143
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/AreaContent.java
@@ -0,0 +1,47 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+public class AreaContent {
+	
+	private Map<String, DataVariable> variables = new TreeMap<>();
+
+	public AreaContent() {}
+	
+	public AreaContent(String name, DataVariable variable) {
+		variables.put(name, variable);
+	}
+	
+	public void addVariable(String name, DataVariable variable) {
+		variables.put(name, variable);
+	}
+	
+	public DataVariable getVariable(String name) {
+		return variables.get(name);
+	}
+	
+	public Set<String> getVariableNames(){
+		return variables.keySet();
+	}
+	
+	public Collection<DataVariable> getVariables(){
+		return variables.values();
+	}
+
+	public DataVariable getVariable(int row, int column) {
+		for(DataVariable var: variables.values()) 
+			if(var.contains(row, column)) return var;
+			//if(var.inHeader(row, column)) return var;
+		
+		return null;
+	}
+
+	public int getVIndex(DataVariable variable, int column) {
+		if(variable == null) return 0;
+		else return variable.getColumnIndex(column);
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/AreaInteractor.java b/src/fr/inria/structgraphics/ui/spreadsheet/AreaInteractor.java
new file mode 100644
index 0000000000000000000000000000000000000000..72c4ac41f278f25dec9add542c9c7acf61f00ef2
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/AreaInteractor.java
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.ui.tools.SelectTool;
+import fr.inria.structgraphics.ui.tools.Tool;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnection;
+import javafx.beans.property.Property;
+import javafx.collections.ObservableList;
+import javafx.scene.control.TablePosition;
+import sun.security.provider.certpath.CollectionCertStore;
+
+public class AreaInteractor {
+	
+	private List<SpreadsheetArea> areas = new ArrayList<>();
+	private DataVariable activeVariable = null;
+	private TransformationField transformField;
+	
+	private SelectTool selectTool;
+	
+	public AreaInteractor(TransformationField transformField){
+		this.transformField = transformField;
+	}
+
+	public List<SpreadsheetArea> getAreas(){
+		return areas;
+	}
+	
+	private LineConnectedCollection selectedCollection;
+	
+	// It controls the interaction with the spreadsheet... 
+	public void clickedOn(ObservableList<TablePosition> selectedCells) { //System.err.println(x);
+		activeVariable = null;
+		
+		if(selectedCells.size() == 1) {
+			TablePosition pos = selectedCells.get(0);
+			
+			for(SpreadsheetArea area: areas) {
+				activeVariable = area.getVariable(pos.getRow(), pos.getColumn());
+				if(activeVariable != null) {
+					int vindex = area.getVIndex(activeVariable, pos.getColumn());
+					transformField.disable(false);
+					transformField.setVariable(activeVariable, vindex); // TODO: ?????
+					
+					int rowindex = pos.getRow() - activeVariable.row - 1;
+					if(rowindex >= 0) {
+						Property property = activeVariable.getProperty(rowindex, vindex);
+						if(property == null) {
+							selectTool.select(null, this);
+							break;
+						}
+						Object obj = property.getBean();
+						
+						if(obj instanceof Mark) {
+							if(selectedCollection != null) {
+								selectedCollection.selectConnection(null);
+								selectedCollection = null;
+							}
+							selectTool.setActive(true);
+							selectTool.select((Mark)obj, this);
+						} else if(obj instanceof FlowConnection) {
+							LineConnectedCollection collection = ((FlowConnection)obj).getCollection();
+							if(selectedCollection != null && selectedCollection != collection) {
+								selectedCollection.selectConnection(null);
+							}
+							
+							collection.selectConnection((FlowConnection)obj);
+							selectedCollection = collection;
+						}
+					} else {
+						if(selectedCollection != null) {
+							selectedCollection.selectConnection(null);
+							selectedCollection = null;
+						}
+						selectTool.select(null, this);
+					}
+
+					return;
+				}
+			}
+		}
+
+		if(selectedCollection != null) {
+			selectedCollection.selectConnection(null);
+			selectedCollection = null;
+		}
+		selectTool.select(null, this);
+		transformField.disable(true);
+		transformField.setDefaultLabel();
+	}
+	
+	public void addArea(SpreadsheetArea area) {
+		areas.add(area);
+	}
+	
+	public void update() { 
+		for(int i = areas.size() - 1; i >=0; --i) {
+			SpreadsheetArea area = areas.get(i);
+			area.clear();
+			if(!area.refresh()) areas.remove(i);
+		}
+	}
+	
+	public void reset() {
+		for(SpreadsheetArea area: areas) {
+			area.clearSketcherLabels();
+			area.clear();
+		}
+		
+		areas.clear();
+	}
+	
+	public DataVariable getActiveVariable() {
+		return activeVariable;
+	}
+
+	public void setSelector(SelectTool select) {
+		this.selectTool = select;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/AreaSourceInfo.java b/src/fr/inria/structgraphics/ui/spreadsheet/AreaSourceInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..96850dc02b6b9940f089d93c88a7a5cfd6983a3f
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/AreaSourceInfo.java
@@ -0,0 +1,114 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.Draggable;
+import fr.inria.structgraphics.ui.Draggable.Type;
+import javafx.beans.property.Property;
+
+public class AreaSourceInfo {
+
+	protected Container source;
+	protected VisBody visbody = null;
+	protected Type type;
+	protected boolean wide = false;
+	protected boolean isNetwork = false;
+	protected ArrayList<PropertyName> names = new ArrayList<>();
+	
+	protected Property property = null; // Only used for single self properties.
+	
+	public AreaSourceInfo(Draggable draggable) {	
+		
+		source = draggable.getContainer();
+		visbody = draggable.getGroup();
+		type = draggable.getType();
+		wide = draggable.isInWide();
+		isNetwork = draggable.isNetwork();
+				
+		//if(source == null || source.getChildPropertyStructure().getProperties().containsKey(key))
+		
+		Object content = draggable.getPropertiesContent();
+		if(content instanceof FlexibleListProperty) {
+			PropertyName propName = ((FlexibleListProperty) content).getPropertyName();
+			names.add(propName);
+
+			if(type == Type.Value) {
+				property = ((FlexibleListProperty) content).get(0);				
+			}
+			
+		} else {
+			for(FlexibleListProperty list: (Collection<FlexibleListProperty>)content) {
+				names.add(list.getPropertyName());				
+			}
+		}
+	}
+	
+	public AreaSourceInfo(Container container, VisBody visbody, ArrayList<PropertyName> names, Type type, boolean isWide, boolean isNetwork) {
+		this.source = container;
+		this.visbody = visbody;
+		this.type = type;
+		this.wide = isWide;
+		this.isNetwork = isNetwork;
+		this.names = names;
+		
+		if(type == Type.Value && !names.isEmpty()) { 
+			property = ((Mark)container).getProperty(names.get(0));
+		}
+	}
+	
+	public Container getSource() {
+		return source;
+	}
+
+	public VisBody getVisBody() {
+		return source.getVirtualGroup();
+	}
+	
+	public Type getType() {
+		return type;
+	}
+	
+	public boolean isWide() {
+		return wide;
+	}
+	
+	public boolean showsNetwork() {
+		return isNetwork;
+	}
+
+	public Property getProperty() {
+		return property;
+	}
+	
+	public ArrayList<PropertyName> getNames(){
+		return names;
+	}
+	
+	public boolean sourceExists() {
+		return (source != null) && (source instanceof VisFrame || source instanceof Mark && ((Mark)source).getRoot() != null);
+	}
+	
+	@Override
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		
+		if(property!= null) buffer.append("? ");
+		else if(wide) buffer.append("> ");
+		
+		for(PropertyName name: names) {
+			buffer.append(name.toString());
+			buffer.append(" ");
+		}
+		
+		buffer.append("\n");
+		
+		return buffer.toString();
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/ColumnVariable.java b/src/fr/inria/structgraphics/ui/spreadsheet/ColumnVariable.java
new file mode 100644
index 0000000000000000000000000000000000000000..52f9dcb24ac57ad3e9dc1e208339661db1af7469
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/ColumnVariable.java
@@ -0,0 +1,57 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import javafx.beans.property.ListProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class ColumnVariable extends DataVariable {
+
+	private ListProperty<Property> properties;
+	protected StringProperty name = new SimpleStringProperty();
+
+	public ColumnVariable(VisBody collection, int row, int column, ListProperty<Property> properties) {
+		super(collection, row, column);
+		name.set(properties.getName());
+		this.properties = properties;		
+		
+		setTransformation();		
+	}
+	
+	public void updateProperties(ListProperty<Property> properties) {
+		this.properties = properties;	
+	}
+	
+	@Override
+	public StringProperty getName(int vindex) {
+		return name;
+	}
+	
+	@Override
+	public String getPropertyName() {
+		return properties.getName();
+	}
+	
+	@Override
+	public int getLength() {
+		return properties.size();
+	}
+	
+	@Override
+	public int getWidth() {
+		return 1;
+	}
+	
+	@Override
+	public Property getProperty(int vindex, int hindex) {
+		return properties.get(vindex);
+	}
+	
+	@Override
+	public boolean contains(int row, int column) {
+		return this.column == column && row >= this.row && row <= this.row + properties.size();
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/ComparableDataValue.java b/src/fr/inria/structgraphics/ui/spreadsheet/ComparableDataValue.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5423b18b81fab3edff04fe49922702ea41a7a03
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/ComparableDataValue.java
@@ -0,0 +1,38 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import javafx.beans.property.Property;
+
+public class ComparableDataValue implements Comparable<ComparableDataValue> {
+
+	private Property value;
+	
+	public ComparableDataValue(Property value) {
+		this.value = value;
+	}
+	
+	public Object getValue() {
+		return value.getValue();
+	}
+	
+	public Property getProperty() {
+		return value;
+	}
+	
+	@Override
+	public int compareTo(ComparableDataValue obj) {
+		if(value.getValue() instanceof Double && obj.value.getValue() instanceof Double)
+			return ((Double)value.getValue()).compareTo((Double)obj.value.getValue());
+		else return value.getValue().toString().compareTo(obj.value.getValue().toString());
+	}
+
+	@Override 
+	public boolean equals(Object obj) {
+		if(obj instanceof ComparableDataValue) return value.getValue().equals(((ComparableDataValue)obj).value.getValue());
+		else return false;
+	}
+	
+	@Override
+	public String toString() {
+		return value.getValue().toString();
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/DataTransformation.java b/src/fr/inria/structgraphics/ui/spreadsheet/DataTransformation.java
new file mode 100644
index 0000000000000000000000000000000000000000..15e0e583eca35b23dc0907277761edcaa36a8479
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/DataTransformation.java
@@ -0,0 +1,31 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.StringProperty;
+
+public abstract class DataTransformation {	
+	protected DataVariable variable;
+	protected StringProperty expression;
+	protected BooleanProperty change = new SimpleBooleanProperty(true);
+
+	public DataTransformation(DataVariable variable) {
+		this.variable = variable;
+	}
+	
+//	public abstract Object fromData(Property source, Object oldValue, Object newValue);
+	public abstract Object fromData(Property source, Object newValue);
+	public abstract String toData(Object val);
+	public abstract boolean setExpression(String expr);
+	
+	public BooleanProperty changeProperty() {
+		return change;
+	}
+	
+	public StringProperty getExpression() {
+		return expression;
+	}
+
+	public void refresh() {}
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/DataTransformationProperty.java b/src/fr/inria/structgraphics/ui/spreadsheet/DataTransformationProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..68fdcec10d664649bd6b1afb727027caea987348
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/DataTransformationProperty.java
@@ -0,0 +1,29 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
+public class DataTransformationProperty extends SimpleObjectProperty<DataTransformation>{
+
+	public DataTransformationProperty() {
+		super();
+	}
+	
+	private ChangeListener listener = new ChangeListener<Boolean>() {
+		@Override
+		public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+			fireValueChangedEvent();
+		}
+	};
+	
+	@Override
+	public void set(DataTransformation transformation) {
+		if(get() != null) get().changeProperty().removeListener(listener);
+		
+		super.set(transformation);
+		transformation.changeProperty().addListener(listener);
+	}
+	
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/DataVariable.java b/src/fr/inria/structgraphics/ui/spreadsheet/DataVariable.java
new file mode 100644
index 0000000000000000000000000000000000000000..41b54a9869d7bdad47dc2638d05157cf7d6beb21
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/DataVariable.java
@@ -0,0 +1,245 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.PropertyName;
+import javafx.beans.InvalidationListener;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
+public abstract class DataVariable {
+
+	public enum DataType {
+		Symbolic, Functional
+	}
+	
+	public BooleanProperty scaleShownProperty = new SimpleBooleanProperty(false);
+	public BooleanProperty scaleShownPropertyOuter = new SimpleBooleanProperty(false);
+	public BooleanProperty legendShownProperty = new SimpleBooleanProperty(false);
+	public BooleanProperty nodeShownProperty = new SimpleBooleanProperty(false);
+	
+	protected MathTransformation mathTransformation;
+	protected DiscreteTransformation discreteTransformation;
+	
+	protected VisBody collection;
+	
+	protected int row, column;
+	protected DataType type = DataType.Functional;
+	protected DataTransformationProperty transformation = new DataTransformationProperty();
+	
+	protected InvalidationListener listener;
+	
+	public DataVariable(VisBody collection, int row, int column) {
+		this.collection = collection;
+		this.row = row;
+		this.column = column;
+		
+		transformation.addListener(new ChangeListener<DataTransformation>() {
+			@Override
+			public void changed(ObservableValue<? extends DataTransformation> observable, DataTransformation oldTransform,
+					DataTransformation newTranform) {
+				if(newTranform instanceof DiscreteTransformation) type = DataType.Symbolic;
+				else type = DataType.Functional;
+			}
+		});
+	}
+	
+	protected void setTransformation() {
+		if(type == DataType.Functional) {
+			if(mathTransformation == null) mathTransformation = new MathTransformation(this);
+			transformation.set(mathTransformation);
+		}
+		else {
+			discreteTransformation = new DiscreteTransformation(this);
+			//if(discreteTransformation == null) discreteTransformation = new DiscreteTransformation(this);
+			transformation.set(discreteTransformation);
+		}
+	}
+	
+	public boolean isConnectionNodeID() {
+		return false;
+	}
+
+	public boolean isNested() {
+		if(collection == null) return false;
+			
+		int level = getLevel() + 1;
+		int colLevel = collection.getLevel();
+		
+		return level < colLevel;		
+	}
+	
+	public abstract String getPropertyName();
+	public abstract int getLength();
+	public abstract int getWidth();
+	public abstract Property getProperty(int vindex, int hindex);
+	public abstract boolean contains(int row, int column);
+	public abstract StringProperty getName(int vindex);
+	
+	public ArrayList<String> getNames(){
+		ArrayList<String> names = new ArrayList<>();
+		for(int i = 0; i < getWidth(); ++i) {
+			names.add(getName(i).get());
+		}
+		
+		return names;
+	}
+		
+	public void setInvalidationListener(InvalidationListener listener) {
+		if(this.listener != null)
+			transformationProperty().removeListener(this.listener);
+		
+		this.listener = listener;
+		transformationProperty().addListener(listener);
+	}
+	
+	public void updatePosition(int row, int column) {
+		this.row = row;
+		this.column = column;
+	}
+	
+	public int getWidth(int row) {
+		return getWidth();
+	}
+
+	public int row() {
+		return row;
+	}
+	public int column() {
+		return column;
+	}
+	
+	public boolean isNumeric() {
+		return firstProperty() instanceof DoubleProperty;
+	}
+	
+	public Property firstProperty() {
+		return getProperty(0, 0);
+	}
+	
+	public DataType getType() {
+		return type;
+	}
+	
+	public DataType getDataType() {
+		return type;
+	}
+	
+	public void setDataType(DataType type) {
+		this.type = type;
+		setTransformation();
+	}
+	
+	public boolean inHeader(int row, int column) {
+		return this.column == column && this.row == row;
+	}
+	
+	public ObjectProperty<DataTransformation> transformationProperty() {
+		return transformation;
+	}
+
+	public int getColumnIndex(int columnIndex) {
+		return 0;
+	}
+	
+	public VisBody getCollection() {
+		return collection;
+	}
+	
+	public List<VisBody> getLevelGroups(){
+		List<VisBody> list = new ArrayList<VisBody>();
+		
+		/*
+		int level = getLevel() + 1;
+		collection.addToGroupLevel(list, level);
+		*/
+		if(collection != null) collection.addToInnerCollections(list);
+				
+		return list;
+	}
+	
+	public List<VisBody> getParentGroup() {
+		List<VisBody> list = new ArrayList<VisBody>();
+		
+		/*
+		int level = getLevel() + 2;
+		if(collection != null) collection.addToParentGroupLevel(list, level);
+		*/
+		if(collection != null) collection.addToOuterCollection(list);
+		
+		return list;		
+	}
+	
+	public boolean isX() {
+		return getPropertyName().contains("x");
+	}
+	
+	public boolean isY() {
+		return getPropertyName().contains("y");
+	}
+	
+	public boolean isWidth() {
+		return getPropertyName().contains("width");
+	}
+	
+	public boolean isHeight() {
+		return getPropertyName().contains("height");
+	}
+	
+	public boolean isWeight() {
+		return getPropertyName().contains("weight");
+	}
+	
+	
+	public boolean isShape() {
+		return getPropertyName().contains("shape");
+	}
+	
+	public boolean isFill() {
+		return getPropertyName().contains("fill");
+	}
+		
+	public boolean isStroke() {
+		return getPropertyName().contains("stroke");
+	}
+	
+	public boolean isThickness() {
+		return getPropertyName().contains("thickness");
+	}
+	
+	public boolean isID() {
+		return getPropertyName().endsWith("id");
+	}
+
+	public int getLevel() {
+		return new PropertyName(getPropertyName()).getLevel();
+		/*
+		String name = getPropertyName();
+		String str = name.replaceAll("[a-z]", "").replace("-", "");
+		if(str.isEmpty()) return 0;
+		else return Integer.parseInt(str);*/
+	}
+	
+	public SortedSet<ComparableDataValue> getDiscreteValues() {
+		SortedSet<ComparableDataValue> list = new TreeSet<>();
+		
+		for(int i = 0; i < getWidth(); ++i) {
+			for(int j = 0; j < getLength(); ++j) {
+				list.add(new ComparableDataValue(getProperty(j, i)));
+			}
+		}
+		return list;
+	}
+
+
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/DataView.java b/src/fr/inria/structgraphics/ui/spreadsheet/DataView.java
new file mode 100644
index 0000000000000000000000000000000000000000..52d1c28e8971d11fe2b85be166b7dfb306dd9a6c
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/DataView.java
@@ -0,0 +1,162 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import java.util.Optional;
+
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.ui.DragManager;
+import fr.inria.structgraphics.ui.inspector.DisplayUtils;
+import fr.inria.structgraphics.ui.inspector.InspectorView;
+import fr.inria.structgraphics.ui.tools.SelectTool;
+import fr.inria.structgraphics.ui.tools.Tool;
+import impl.org.controlsfx.spreadsheet.CellView;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.geometry.Orientation;
+import javafx.scene.Node;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Separator;
+import javafx.scene.control.ToolBar;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.DragEvent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.PickResult;
+import javafx.scene.input.TransferMode;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+
+public class DataView extends BorderPane {
+	
+	public static final String STYLESHEETS = DataView.class.getResource("spreadsheet.css").toExternalForm();
+
+	private Spreadsheet spreadsheet;
+	private TransformationField transformField;
+	
+	private InspectorView inspector;
+	private AreaInteractor interactor;
+	
+	public DataView(InspectorView inspector) {
+		this.inspector = inspector;
+		inspector.setDataView(this);
+		
+		buildUI();
+	}	
+	
+	public Spreadsheet getSpreadsheet() {
+		return spreadsheet;
+	}
+	
+	private void cleanSpreadsheet() {
+		spreadsheet.clean();
+		transformField.disable(true);
+		transformField.setDefaultLabel();
+	}
+	
+	private void buildUI() {		
+		Button clean = new Button("Clean", new ImageView(DisplayUtils.getIcon("cleaning")));
+		clean.setOnAction(
+				new EventHandler<ActionEvent>() {
+					@Override public void handle(ActionEvent e) {
+						Alert alert = new Alert(AlertType.CONFIRMATION);
+						alert.setTitle("Confirmation Dialog");
+						alert.setHeaderText(null);
+						alert.setContentText("Are you sure you want to clean the spreadsheet?");
+
+						Optional<ButtonType> result = alert.showAndWait();
+						if (result.get() == ButtonType.OK){
+							cleanSpreadsheet();
+						} else {
+							// ... user chose CANCEL or closed the dialog
+						}
+					}
+				});
+
+		HBox toolBar = new HBox(clean);
+		toolBar.getChildren().add(new Separator(Orientation.VERTICAL));
+		
+		transformField = new TransformationField(toolBar);
+		StackPane stack = new StackPane();
+		
+		interactor = new AreaInteractor(transformField);
+		spreadsheet = new Spreadsheet(this, interactor);
+			
+		stack.getChildren().setAll(spreadsheet);
+	
+		setTop(transformField);
+		setCenter(stack);
+						
+		spreadsheet.setOnDragOver(new EventHandler<DragEvent>() {
+		    public void handle(DragEvent event) {
+		    	Dragboard db = event.getDragboard();
+		    	
+		        /* data is dragged over the target */
+		        /* accept it only if it is not dragged from the same node 
+		         * and if it has a string data */
+		        if (event.getGestureSource() != spreadsheet && db.hasString()) {
+		            /* allow for both copying and moving, whatever user chooses */
+		            event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+		           
+		            PickResult pick = event.getPickResult();
+		            if(pick != null) {
+		            	Node node = pick.getIntersectedNode();
+		            	
+		            	if(node instanceof CellView  && db.getString().equals(DragManager.DRAG_CODE)) {
+		            		int columns = inspector.getDragged().getColumnsNum();
+		            		int rows = inspector.getDragged().getRowsNum();
+		            		
+		            		CellView cellView = (CellView)node;
+		            		spreadsheet.dragOver(cellView, rows, columns);
+		            	}
+		            }
+		            
+		           // spreadsheetView.addEventHandler(MouseEvent.MOUSE_MOVED, eventHandler);
+		        }
+
+		        event.consume();
+		    }
+		});
+				
+		spreadsheet.setOnDragDropped(new EventHandler <DragEvent>() {
+	            public void handle(DragEvent event) {
+	                /* data dropped */
+	                /* if there is a string data on dragboard, read it and use it */
+	                Dragboard db = event.getDragboard();
+	                boolean success = false;
+	                if (db.hasString() && db.getString().equals(DragManager.DRAG_CODE)) {
+	                	spreadsheet.dragEnded(inspector.getDragged());
+	                    success = true;
+	                }
+	                /* let the source know whether the string was successfully 
+	                 * transferred and used */
+	                event.setDropCompleted(success);
+	                
+	                event.consume();
+	            }
+	        });
+	}
+	
+	public VisFrame getVisFrame() {
+		return inspector.getVisualizationFrame();
+	}
+	
+	public void reset() {
+		spreadsheet.reset();
+		transformField.disable(true);
+		transformField.setDefaultLabel();
+	}
+
+	public void setSelector(SelectTool select) {
+		interactor.setSelector(select);
+	}
+
+	public void update() {
+		spreadsheet.update();
+	}
+}
+
+
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/DiscreteTransformation.java b/src/fr/inria/structgraphics/ui/spreadsheet/DiscreteTransformation.java
new file mode 100644
index 0000000000000000000000000000000000000000..010b369b52f5452e1886635736b14de908094fa4
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/DiscreteTransformation.java
@@ -0,0 +1,188 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
+public class DiscreteTransformation extends DataTransformation {
+	
+	private final static String[] DEFAULT_CATEGORIES = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
+	
+	private TreeMap<MappingProperty, StringProperty> map;
+	private int i = 0;
+	
+	private Hashtable<Mark, String> symbols = new Hashtable<>();
+	
+	public DiscreteTransformation(DataVariable variable) {
+		super(variable);
+		
+		expression = new SimpleStringProperty();
+		
+		PropertySet propertySet = new PropertySet(variable);
+		map = new TreeMap<>();
+						
+		for(MappingProperty property: propertySet) {	
+			MappingProperty copy = property.getCopy();
+			
+			// TODO: This is to synchronize the x,y with the mapped symbols
+			// I may need to consider two different types of discrete transforms to
+			// support this behavior
+			if(variable.isX() || variable.isY()) copy.bind(property);
+			
+			SimpleStringProperty symbol = (i < DEFAULT_CATEGORIES.length) ?  new SimpleStringProperty(DEFAULT_CATEGORIES[i++]) : new SimpleStringProperty("A" + (i++));			
+			symbols.put((Mark)property.getBean(), symbol.get());
+			map.put(copy, symbol);
+			
+			property.addListener(new ChangeListener() {
+				@Override
+				public void changed(ObservableValue observable, Object oldValue, Object newValue) {
+					updateExpression();
+					// TODO: Need to find a way to handle Ids!!!
+				}
+			});
+		}
+		
+		updateExpression();
+		change.set(!change.get());
+	}
+	
+	void printMap() {
+		for(MappingProperty prop:map.keySet()) {
+			System.err.println(prop + "----> " + map.get(prop));
+		}
+	}
+	
+	public TreeMap<MappingProperty, StringProperty> getMap(){
+		return map;
+	}
+
+	@Override
+	public void refresh() {
+		/////
+		PropertySet propertySet = new PropertySet(variable);
+		
+		TreeMap<MappingProperty, StringProperty> map_ = new TreeMap<>();
+		for(MappingProperty property: propertySet) {
+			MappingProperty copy = property.getCopy();
+			
+			// TODO: This is to synchronize the x,y with the mapped symbols
+			// I may need to consider two different types of discrete transforms to
+			// support this behavior
+			if(variable.isX() || variable.isY()) copy.bind(property);
+			
+			if(map.containsKey(property)) map_.put(copy, map.get(property));
+			else {
+				String symbol = symbols.get((Mark)property.getBean());
+				if(symbol == null)
+					map_.put(copy, (i < DEFAULT_CATEGORIES.length) ?  new SimpleStringProperty(DEFAULT_CATEGORIES[i++]) : new SimpleStringProperty("A" + (i++)));
+				else map_.put(copy, new SimpleStringProperty(symbol));
+			}
+		}
+		
+		map.clear();
+		map = map_;
+		
+		updateExpression();
+	}
+	
+
+	public void replace(String from, String to) {
+		for(MappingProperty prop: map.keySet()) {
+			if(prop.get().toString().equals(from)) {
+				map.get(prop).set(to);
+				symbols.put((Mark)prop.getBean(), to);	
+				updateExpression();
+				change.set(!change.get());
+			}				
+		}
+	}
+	
+	@Override
+	public Object fromData(Property source/*, Object oldValue*/, Object newValue) {
+		if(variable.isID()) {
+			for(MappingProperty prop: map.keySet()) {
+				if(prop.getValue().equals(source.getValue())) {
+					map.get(prop).set(newValue.toString());
+					symbols.put((Mark)prop.getBean(), newValue.toString());	
+					updateExpression();
+					change.set(!change.get());
+					return prop.get();
+				}				
+			}
+		}
+		
+		
+		// TODO: Do it better!!!
+		for(MappingProperty prop: map.keySet()) {
+			if(map.get(prop).get().equals(newValue)) {
+				symbols.put((Mark)prop.getBean(), newValue.toString());				
+				return prop.get();
+			}
+		}
+
+		String oldValue = toData(source.getValue());
+		for(MappingProperty prop: map.keySet()) {
+			StringProperty entry = map.get(prop);
+			if(entry.get().equals(oldValue)) { // System.err.println(prop + " >>> " + newValue);
+				map.get(prop).set(newValue.toString());
+				symbols.put((Mark)prop.getBean(), newValue.toString());				
+				
+			//	map.put(prop, new SimpleStringProperty(newValue.toString())); // TODO Update this!!!!!!
+				updateExpression();
+				change.set(!change.get());
+				return prop.get();
+			}
+		}
+		
+		return null;
+	}
+	
+	
+	@Override
+	public String toData(Object val) { 
+		StringProperty value = map.get(new MappingProperty(val));
+		if(value != null) return map.get(new MappingProperty(val)).get();
+		else return null;
+	}
+	
+	@Override
+	public boolean setExpression(String expr) {
+		change.set(!change.get());
+		
+		return false;
+	}
+	
+	private void updateExpression() {
+		StringBuffer str = new StringBuffer(variable.getPropertyName() + ": ");
+
+		List<MappingProperty> unmapped = new ArrayList<>();
+		for(MappingProperty prop:map.keySet()) {
+			StringProperty value = map.get(prop);
+			if(value != null)
+				str.append("{ " + prop.get() + " -> " + value.get() + " } ");
+			else // TODO: ....
+				str.append("{ " + prop.get() + " -> " + "?" + " } ");
+		}
+		
+		expression.set(str.substring(0, str.length() - 1));
+		
+		//System.err.println(expression.get());
+		// TODO: There is still some buggy behavior, not sure why.... 
+	}
+
+	/*
+	public void update(Object value, String newValue) { 
+		map.put(new MappingProperty(value), new SimpleStringProperty(newValue));
+		updateExpression();
+	}*/
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/MappingProperty.java b/src/fr/inria/structgraphics/ui/spreadsheet/MappingProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b5864d7416aae6a171e67c1d516332ba2865103
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/MappingProperty.java
@@ -0,0 +1,54 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
+public class MappingProperty extends SimpleObjectProperty<Object> implements Comparable<MappingProperty> {
+
+	public MappingProperty(Property property) {
+		super(property.getBean(), property.getName());
+		set(property.getValue());
+		this.bind(property);
+	}
+	
+	public MappingProperty(Object obj) {
+		set(obj);
+	}
+	
+	public MappingProperty(Object bean, String name) {
+		super(bean, name);
+	}
+
+	@Override
+	public int compareTo(MappingProperty prop) {
+		if(equals(prop)) {
+			return 0;
+		}
+		else {
+			if(get() instanceof Double) return ((Double)get()).compareTo((Double)prop.get());
+			else return get().toString().compareTo(prop.get().toString());		
+		}
+	}
+	
+	public MappingProperty getCopy() {
+		MappingProperty copy = new MappingProperty(getBean(), getName());
+		copy.set(this.get());
+		
+		return copy;
+	}
+	
+	@Override
+	public boolean equals(Object o) { 
+		if(o instanceof Property) {
+			Object val1 = getValue();
+			Object val2 = ((Property)o).getValue();
+			if(val1 instanceof Double && val2 instanceof Double) {
+				return Math.abs(((Double)val1) - ((Double)val2)) < .001;
+			}
+			else return ((Property)o).getValue().equals(getValue());
+		}
+		else return false;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/MathTransformation.java b/src/fr/inria/structgraphics/ui/spreadsheet/MathTransformation.java
new file mode 100644
index 0000000000000000000000000000000000000000..d99b205e5d20574b103202b0f50cf7f80b03f140
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/MathTransformation.java
@@ -0,0 +1,240 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import java.text.DecimalFormat;
+
+import org.matheclipse.core.eval.ExprEvaluator;
+import org.matheclipse.core.interfaces.IExpr;
+import org.matheclipse.parser.client.SyntaxError;
+import org.matheclipse.parser.client.math.MathException;
+
+import fr.inria.structgraphics.types.AlignmentXProperty;
+import fr.inria.structgraphics.types.AlignmentYProperty;
+import fr.inria.structgraphics.types.ColorProperty;
+import fr.inria.structgraphics.types.ComponentRefXProperty;
+import fr.inria.structgraphics.types.ComponentRefYProperty;
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.ui.inspector.ColorStringConverter;
+import fr.inria.structgraphics.ui.inspector.DoubleStringConverter;
+import fr.inria.structgraphics.ui.inspector.GeneralStringConverter;
+import fr.inria.structgraphics.ui.inspector.RefXStringConverter;
+import fr.inria.structgraphics.ui.inspector.RefYStringConverter;
+import fr.inria.structgraphics.ui.inspector.ShapeStringConverter;
+import fr.inria.structgraphics.ui.inspector.XAlignmentStringConverter;
+import fr.inria.structgraphics.ui.inspector.YAlignmentStringConverter;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+
+public class MathTransformation extends DataTransformation {
+	private boolean decimals = false;
+	
+	private StringProperty invexpression;
+	private GeneralStringConverter converter;
+
+	private StringProperty expression0;
+	
+	private String varName;
+	
+	public MathTransformation(DataVariable variable) {
+		super(variable);
+		
+		expression0 = new SimpleStringProperty(variable.getPropertyName());
+		varName = fixVarName(variable.getPropertyName());
+		expression = new SimpleStringProperty(varName);
+		invexpression = new SimpleStringProperty("$Y");
+		
+		expression0.addListener(new ChangeListener<String>() {
+			@Override
+			public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
+				expression.set(fixVarName(newValue));
+			}
+		});
+		
+		expression.addListener(new ChangeListener<String>() {
+			@Override
+			public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
+				expression0.set(newValue.replaceAll(varName, variable.getPropertyName()));
+			}
+		});
+		
+		Property prop = variable.firstProperty();
+		if(prop instanceof ColorProperty) {
+			converter = new ColorStringConverter();
+		} else if(prop instanceof ShapeProperty) {
+			converter = new ShapeStringConverter();
+		} else if(prop instanceof DoubleProperty) {
+			converter = new DoubleStringConverter();
+		} else if(prop instanceof AlignmentXProperty) {
+			converter = new XAlignmentStringConverter();
+		} else if(prop instanceof AlignmentYProperty) {
+			converter = new YAlignmentStringConverter();
+		} else if(prop instanceof ComponentRefXProperty) {
+			converter = new  RefXStringConverter();
+		} else if(prop instanceof ComponentRefYProperty) {
+			converter = new  RefYStringConverter();
+		}
+	}
+
+	@Override
+	public Object fromData(Property source, /*Object oldValue,*/ Object newValue) {
+		if(variable.firstProperty() instanceof ColorProperty) {
+			String stringValue = newValue.toString();
+			if(stringValue == null || stringValue.isEmpty()) newValue = toData(source.getValue());//oldValue;
+			
+			/*
+			long val = paintToNumber(newValue.toString());
+			ExprEvaluator util = new ExprEvaluator();
+			String expr = "$Y=" + val + ";" + invexpression.get();		
+			IExpr result = util.evaluate(expr);
+			*/
+			return stringToPaint(newValue.toString());
+			//return stringToPaint(newValue);
+		} else if(variable.firstProperty() instanceof DoubleProperty) {
+			double val;
+			
+			try{
+				val = Double.parseDouble(newValue.toString());
+				
+				ExprEvaluator util = new ExprEvaluator();
+				String expr = "$Y=" + val + ";" + invexpression.get();	
+				IExpr result = util.evaluate(expr);	
+				
+				return result.evalDouble(); 
+
+			} catch(NumberFormatException e) {
+				//val = Double.parseDouble(oldValue.toString());
+				return source.getValue();
+			}	
+			
+		} else if(variable.firstProperty() instanceof StringProperty) {
+			return newValue;
+		}
+		else return converter.fromString(newValue.toString());
+	}
+	
+	
+	public double transform(Object val) {
+		if(val instanceof Double){
+			ExprEvaluator util = new ExprEvaluator();
+			String expr = varName + "=" + val +";" + expression.get();
+			return util.evaluate(expr).evalDouble();	
+		} else return 0;
+	}
+	
+	public double inverseTransform(double val) {
+		ExprEvaluator util = new ExprEvaluator();
+		String expr = "$Y=" + val + ";" + invexpression.get();	
+		IExpr result = util.evaluate(expr);	
+		
+		return result.evalDouble(); 
+	}
+	
+	@Override
+	public String toData(Object val) {
+		if(val instanceof Paint) {
+			//ExprEvaluator util = new ExprEvaluator();
+			//String expr = varName + "=" + val +";" + expression.get();
+			
+			//return numberToPaint((long) util.evaluate(expr).evalDouble()).toString();
+			return val.toString();
+		} else if(val instanceof Double){
+			DecimalFormat df = new DecimalFormat(decimals ? "#.0" : "#"); 
+			
+			ExprEvaluator util = new ExprEvaluator();
+			String expr = varName + "=" + val +";" + expression.get();
+		
+			return df.format(util.evaluate(expr).evalDouble());	
+		} else if(val instanceof String || converter == null) {
+			return val.toString();
+		}
+		else {
+			return converter.toString(val);
+		}
+	}
+	
+	private Paint stringToPaint(String string) {
+		Color color;
+		try {
+			color = Color.web(string);
+		} catch(Exception e) {
+			color = Color.LIGHTGRAY;
+		}
+		
+		return color;
+	}
+	
+	/*
+	private Long paintToString(String paintValue) { 
+		Color color;
+		
+		try {
+			color = Color.web(paintValue);
+		} catch(Exception e) {
+			color = Color.LIGHTGRAY;
+		}
+				
+		return Long.parseLong(color.toString().substring(2), 16);		
+	}
+	
+	private Paint stringToPaint(String string) {
+		try {
+			//return Paint.valueOf("0x" + Long.toHexString(number));
+			return Paint.valueOf(string);
+		} catch(IllegalArgumentException e) {
+			return null;
+		}
+	}*/
+	
+	@Override
+	public StringProperty getExpression() {
+		return expression0;
+	}
+	
+	@Override
+	public boolean setExpression(String expr) { 
+		expr = fixVarName(expr);
+		
+		if(!expr.contains(varName)) return false;
+		
+		try {
+			ExprEvaluator util = new ExprEvaluator();
+			IExpr result = util.evaluate(expr);
+			expr = result.toString();
+			if(!expr.contains(varName)) return false;
+			
+			/*
+			if(expr.contains("Abs(" + varName + ")")) {
+				expr.replaceAll("Abs(" + varName + ")", varName);
+				isAbsolute = true;
+			}*/
+			
+			String str = "Roots($Y==" + expr + ", " +  varName +")";			
+			str = util.evaluate(str).toString();
+			
+			invexpression.set(str.substring(str.indexOf("=") + 2));
+			expression.set(expr);
+			change.set(!change.get());
+			
+			return true;
+		} catch (SyntaxError e) {
+			return false;
+        } catch (MathException me) { 
+        	return false;
+        } catch (Exception e) {
+        	return false;
+        }
+	}
+	
+	
+	// This is to artificially fix the variable name problems!!!!
+	private static String fixVarName(String var) {
+		return var.replaceAll("[A-Z].", "").replaceAll("[a-z]-[x-y]", "");
+	}
+	
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/MultiColumnVariable.java b/src/fr/inria/structgraphics/ui/spreadsheet/MultiColumnVariable.java
new file mode 100644
index 0000000000000000000000000000000000000000..c0482151e6bb73a6e655cc9bde7a64b8032b4711
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/MultiColumnVariable.java
@@ -0,0 +1,95 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import javafx.beans.property.ListProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class MultiColumnVariable extends DataVariable {
+
+	private ListProperty<Property> properties;
+	protected List<SimpleStringProperty> names = new ArrayList<SimpleStringProperty>();
+
+	private boolean isConnectionId = false;
+	
+	public MultiColumnVariable(VisBody collection, int row, int column, ListProperty<Property> properties) {
+		super(collection, row, column);
+		this.properties = properties;		
+		
+		for(int i=0; i < getWidth(); ++i)
+			names.add(new SimpleStringProperty(properties.getName()));
+				
+		setTransformation();		
+	}
+	
+	@Override
+	public String getPropertyName() {
+		return properties.getName();
+	}
+	
+	public void setConnectionId() {
+		isConnectionId = true;
+	}
+	
+	public void updateProperties(ListProperty<Property> properties) {
+		this.properties = properties;	
+	}
+
+	@Override
+	public StringProperty getName(int vindex) {
+		return names.get(vindex);
+	}
+	
+	@Override 
+	public int getWidth() {
+		int w = 0;
+		for(int i = 0; i < getLength(); ++i) {
+			w = Math.max(w, getWidth(i));
+		}
+		
+		return w;
+	}
+	
+	public boolean isConnectionNodeID() {
+		return isConnectionId;
+	}
+	
+	@Override
+	public int getWidth(int vindex) {
+		Property prop = properties.get(vindex);
+		if(prop instanceof ListProperty) return ((ListProperty)properties.get(vindex)).size();
+		else return 1;
+	}
+	
+	@Override
+	public int getLength() {
+		return properties.getSize(); 
+	}
+	
+	@Override
+	public int getColumnIndex(int columnIndex) {
+		return columnIndex - this.column;
+	}
+	
+	@Override
+	public Property getProperty(int vindex, int hindex) {
+		Property prop = properties.get(vindex);
+		if(prop instanceof ListProperty) {
+			if(hindex < getWidth(vindex)) return (Property) ((ListProperty)prop).get(hindex);
+			else return null;
+		}
+		else if(hindex < 1) return prop;
+		else return null;
+	}
+	
+	@Override
+	public boolean contains(int row, int column) {
+		return column >= this.column && column < this.column + getWidth() && row >= this.row && row <= this.row + getLength();
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/NumberAxis.png b/src/fr/inria/structgraphics/ui/spreadsheet/NumberAxis.png
new file mode 100644
index 0000000000000000000000000000000000000000..ecb97343eb6de53d8b3f4fc35f468704f01d9b84
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/spreadsheet/NumberAxis.png differ
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/PropertySet.java b/src/fr/inria/structgraphics/ui/spreadsheet/PropertySet.java
new file mode 100644
index 0000000000000000000000000000000000000000..5df1753be44f48333603a910230bfc3036c122fe
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/PropertySet.java
@@ -0,0 +1,13 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import java.util.TreeSet;
+
+public class PropertySet extends TreeSet<MappingProperty> {
+
+	public PropertySet(DataVariable variable) {
+		for(int i = 0; i < variable.getLength(); ++i) {
+			for(int j = 0; j< variable.getWidth(); ++j)
+				add(new MappingProperty(variable.getProperty(i, j)));
+		}
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/Spreadsheet.java b/src/fr/inria/structgraphics/ui/spreadsheet/Spreadsheet.java
new file mode 100644
index 0000000000000000000000000000000000000000..fe3c3cb83d496ff885f3b21b0aa3661e692b44a5
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/Spreadsheet.java
@@ -0,0 +1,572 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import static impl.org.controlsfx.i18n.Localization.asKey;
+import static impl.org.controlsfx.i18n.Localization.localize;
+
+import java.util.List;
+import org.controlsfx.control.spreadsheet.Grid;
+import org.controlsfx.control.spreadsheet.GridBase;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell.CornerPosition;
+
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.types.ColorProperty;
+import fr.inria.structgraphics.types.ConstrainedDoubleProperty;
+import fr.inria.structgraphics.ui.Draggable;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable.DataType;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnection;
+
+import org.controlsfx.control.spreadsheet.SpreadsheetCellType;
+import org.controlsfx.control.spreadsheet.SpreadsheetColumn;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+import impl.org.controlsfx.spreadsheet.CellView;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.Property;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+
+import javafx.event.EventHandler;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.TablePosition;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.Clipboard;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Rectangle;
+
+public class Spreadsheet extends SpreadsheetView {
+	
+	private ObservableList<ObservableList<SpreadsheetCell>>	rows;
+
+	private DataView dataView;
+	private AreaInteractor interactor;
+	private SpreadsheetArea dragOverArea = null;
+	private MenuItem showAxis, showParentAxis, showLegend, showNode; 
+	
+	public Spreadsheet(DataView dataView, AreaInteractor interactor) {
+		super(createEmptyGrid());
+
+		this.dataView = dataView;
+		
+	    for(SpreadsheetColumn column: getColumns()){
+	          column.setPrefWidth(100);
+	    }
+	    
+	    rows = getGrid().getRows();
+	    
+	    getChildren().get(0).setOnMouseClicked(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {				
+				DataVariable variable = interactor.getActiveVariable();
+				
+				interactor.clickedOn(getSelectionModel().getSelectedCells());
+				if(variable == null) {
+					showAxis.setDisable(true);
+					showParentAxis.setDisable(true);
+					showLegend.setDisable(true);
+				}
+				else {
+					if((variable.isX() || variable.isY() || variable.isHeight()) && variable.isNested()) {
+						showAxis.setDisable(false);
+						if(!variable.scaleShownProperty.get())
+							showAxis.setText("Show on inner axis");
+						else showAxis.setText("Hide from inner axis");
+					} else showAxis.setDisable(true);
+					
+					if(!variable.getParentGroup().isEmpty() && ((variable.isX() /*&& !variable.isNested()*/) || variable.isY() || variable.isHeight() || (variable.isWidth() /*&& !variable.isNested()*/) )) { // TODO: Check if there is a parent axis!!!!
+						showParentAxis.setDisable(false);
+						if(!variable.scaleShownPropertyOuter.get())
+							showParentAxis.setText("Show on outer axis");
+						else showParentAxis.setText("Hide from outer axis");
+					} else showParentAxis.setDisable(true);
+					
+					if(/*(variable.isFill() || variable.isShape() || variable.isStroke() || variable.isThickness()) &&*/ variable.type == DataType.Symbolic) {
+						showLegend.setDisable(false);
+						if(!variable.legendShownProperty.get())
+							showLegend.setText("Show on legend");
+						else showLegend.setText("Hide from legend");	
+					} else showLegend.setDisable(true);
+					
+					if(variable.isID() || variable.isX() || variable.isY() || variable.isHeight() || variable.isWidth() || variable.isWeight()
+							|| variable.isStroke()) {
+						showNode.setDisable(false);
+						if(!variable.nodeShownProperty.get())
+							showNode.setText("Show on glyphs");
+						else showNode.setText("Hide from glyphs");	
+					} else showNode.setDisable(true);
+				}
+			}
+		});
+	    
+	    this.interactor = interactor;
+	}
+	
+		
+	public List<SpreadsheetArea> getAreas() {
+		return interactor.getAreas();
+	}
+	
+	public void addArea(SpreadsheetArea area) {
+		interactor.addArea(area);
+	}
+	
+	public void setCellValues(int row, int column, DataVariable variable) {
+		for(int i = 0; i < variable.getLength(); ++i) {
+			for(int j = 0; j < variable.getWidth(i); ++j)
+				setCellValue(row + i, column + j, i, j, variable);
+		}	
+	}
+	
+	public void setCellValue(int row, int column, int vindex, int hindex, DataVariable variable) {
+		SpreadsheetCellAdaptable cell = (SpreadsheetCellAdaptable)getCell(row, column);
+		Property property = variable.getProperty(vindex, hindex);
+		
+		cell.setType(SpreadsheetCellType.OBJECT);
+		cell.setGraphic(null);
+			
+		// TODO: For now, I only handle double properties.... I will come back here later and fix the rest of the types!!!! 
+		// TODO: This is tricky!!!!
+		cell.setPropertyListener(property, new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				//if(cell.isPropertyListenerLocked()) return;
+				
+				cell.lockCellListener(true);
+				String value = variable.transformation.get().toData(property.getValue());
+				if(value!=null) cell.itemProperty().set(value);
+				cell.lockCellListener(false);
+				
+				if(property instanceof ColorProperty) cell.setStyle("-fx-background-color: #" + property.getValue().toString().substring(2) + ";");
+			}
+		}); 
+
+		cell.itemProperty().set(variable.transformation.get().toData(property.getValue())); // Init the value....
+		if(property instanceof ColorProperty) cell.setStyle("-fx-background-color: #" + property.getValue().toString().substring(2) + ";");
+		
+		
+		cell.setCellListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+	
+				if(cell.isCellListenerLocked()) return;				
+				//cell.lockPropertyListener(true);
+				
+	            if (property instanceof ConstrainedDoubleProperty) {
+	               ((ConstrainedDoubleProperty)property).updateValue((double) variable.transformation.get().fromData(property, cell.getText())); 
+	            }
+	            else property.setValue(variable.transformation.get().fromData(property, cell.getText()));	
+	            
+				//cell.lockPropertyListener(false);
+			}
+		});
+		
+		/*
+		cell.setCellListener(new ChangeListener<Object>() {
+			@Override
+			public void changed(ObservableValue<? extends Object> observable, Object oldValue, Object newValue) {
+	
+				if(cell.isCellListenerLocked()) return;				
+				//cell.lockPropertyListener(true);
+				
+	            if (property instanceof ConstrainedDoubleProperty) {
+	               ((ConstrainedDoubleProperty)property).updateValue((double) variable.transformation.get().fromData(property, oldValue, newValue)); 
+	            }
+	            else property.setValue(variable.transformation.get().fromData(property, oldValue, newValue));	
+	            
+				//cell.lockPropertyListener(false);
+			}
+		});*/
+		
+	}
+	
+	
+	public void setCellLabel(int row, int column, int vindex, DataVariable variable) {
+		SpreadsheetCellAdaptable cell = (SpreadsheetCellAdaptable)getCell(row, column);
+		cell.setType(SpreadsheetCellType.STRING);
+		
+		Circle circle = new Circle(0,0,5);
+		circle.setStroke(Color.CORNFLOWERBLUE);
+		circle.setFill(null);
+		cell.setGraphic(circle);
+		
+		cell.setStyle("-fx-background-color: #cece0d;");		
+		
+		cell.itemProperty().set(variable.getName(vindex).get());
+		cell.setCellListener(new InvalidationListener() {
+			/*
+			@Override
+			public void changed(ObservableValue observable, Object oldValue Object newValue) {
+				StringProperty name = variable.getName(vindex);
+				if(name != null) name.set(newValue.toString());
+			}*/
+
+			@Override
+			public void invalidated(Observable observable) {
+				StringProperty name = variable.getName(vindex);
+				if(name != null) name.set(cell.getText());
+			}
+		});
+		variable.getName(vindex).addListener(new ChangeListener<String>() {
+			@Override
+			public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
+				cell.itemProperty().set(newValue);
+			}
+		});
+	}
+
+	public void setCellLabel(int row, int column, String newName) {
+		SpreadsheetCellAdaptable cell = (SpreadsheetCellAdaptable)getCell(row, column);
+		cell.itemProperty().set(newName);
+	}
+	
+	public void clear(int row, int column) {// System.err.println("clear " + row + ", " + column);
+		SpreadsheetCellAdaptable cell = (SpreadsheetCellAdaptable)getCell(row, column);
+		cell.setCellListener(null);
+		cell.setPropertyListener(null, null);
+		cell.setGraphic(null);
+		
+		cell.setType(SpreadsheetCellType.STRING);
+		cell.setStyle("-fx-background-color: #ffffff;");
+		cell.itemProperty().set("");	
+		
+		cell.deactivateCorner(CornerPosition.BOTTOM_LEFT);
+		cell.deactivateCorner(CornerPosition.BOTTOM_RIGHT);
+		cell.deactivateCorner(CornerPosition.TOP_LEFT);
+		cell.deactivateCorner(CornerPosition.TOP_RIGHT);
+	}
+	
+	
+	private static Grid createEmptyGrid() {
+		GridBase grid = new GridBase(800, 26);
+
+	     ObservableList<ObservableList<SpreadsheetCell>> rows = FXCollections.observableArrayList();
+	     for (int row = 0; row < grid.getRowCount(); ++row) {
+	         final ObservableList<SpreadsheetCell> list = FXCollections.observableArrayList();
+	         for (int column = 0; column < grid.getColumnCount(); ++column) {
+	             //list.add(SpreadsheetCellType.DOUBLE.createCell(row, column, 1, 1, null));
+	        	 SpreadsheetCellAdaptable cell = new SpreadsheetCellAdaptable(row, column, 1, 1, SpreadsheetCellType.OBJECT);
+
+	        	 //cell.addEventHandler(eventType, eventHandler);
+	        	 
+	        	 list.add(cell);
+	         }
+	         rows.add(list);
+	     }
+	     grid.setRows(rows);
+	     
+	     return grid;
+	}
+	
+	
+	public static int toColumnIndex(CellView cellView) {
+		return cellView.getTableView().getColumns().indexOf(cellView.getTableColumn());
+	}
+	
+	public SpreadsheetCellAdaptable getCell(int row, int column) {		
+		return (SpreadsheetCellAdaptable)rows.get(row).get(column);
+	}
+
+	public SpreadsheetCellAdaptable getCell(int row, String columnName) {
+		return getCell(row, columnName.charAt(0) - 'A');
+	}
+		
+	public SpreadsheetCellAdaptable toCell(CellView cellView) {
+		return getCell(cellView.getIndex(), cellView.getTableColumn().getText());
+	}
+	
+	public void dragOver(CellView cellView, int width, int height) {		
+		if(dragOverArea != null) {
+			dragOverArea.updateDrag(cellView);
+		}
+		else dragOverArea = new SpreadsheetArea(this, cellView, width, height);
+		
+		dragOverArea.updateDrag(cellView);
+	}
+	
+	public void dragEnded(Draggable draggable) {		
+		if(dragOverArea != null) dragOverArea.dragEnded();
+		dragOverArea.setContent(draggable);
+		
+		if(dragOverArea != null) {
+			interactor.addArea(dragOverArea);
+			dragOverArea = null;
+		}
+	}
+
+	public void reset() {
+		dragOverArea = null;
+		
+		setGrid(createEmptyGrid());
+
+	    for(SpreadsheetColumn column: getColumns()){
+	          column.setPrefWidth(100);
+	    }
+	    
+	    rows = getGrid().getRows();
+	    interactor.reset();
+	}
+	
+	
+	private void markVariable(DataVariable variable, SpreadsheetCell.CornerPosition position, boolean activate) {
+		int row = variable.row();
+		int column = variable.column();
+		int width = variable.getWidth();
+		
+		for(int i = 0; i < width; ++i) {
+			SpreadsheetCell cell = getGrid().getRows().get(row).get(column + i);
+			if(activate) cell.activateCorner(position);
+			else cell.deactivateCorner(position);
+		}
+	}
+	
+	private void showOnGraph() {
+		showOnGraph(interactor.getActiveVariable());
+	}
+	
+	private void showOnParentGraph() {
+		showOnParentGraph(interactor.getActiveVariable());
+	}
+	
+	private void showOnLegend() {
+		showOnLegend(interactor.getActiveVariable());
+	}	
+
+	private void showOnNode() {
+		showOnNode(interactor.getActiveVariable());
+	}	
+	
+	public void showOnGraph(DataVariable variable) {
+		if(variable != null) {			
+            markVariable(variable, SpreadsheetCell.CornerPosition.TOP_LEFT, !variable.scaleShownProperty.get());
+			
+           	List<VisBody> collections = variable.getLevelGroups();
+           	for(VisBody collection: collections) ((VisCollection)collection).showVariableOnAxis(variable, false);
+ 			
+			variable.scaleShownProperty.set(!variable.scaleShownProperty.get());
+			
+			if(variable.scaleShownProperty.get()) {
+				variable.scaleShownProperty.addListener(new InvalidationListener() {
+					@Override
+					public void invalidated(Observable observable) {
+						markVariable(variable, SpreadsheetCell.CornerPosition.TOP_LEFT, false);
+						variable.scaleShownProperty.removeListener(this);
+					}
+				});
+			}
+		}
+	}
+	
+	public void showOnParentGraph(DataVariable variable) {
+		if(variable != null) {		
+            markVariable(variable, SpreadsheetCell.CornerPosition.BOTTOM_LEFT, !variable.scaleShownPropertyOuter.get());
+
+           	List<VisBody> collections = variable.getParentGroup();
+           	for(VisBody collection: collections) {
+           		((VisCollection)collection).showVariableOnAxis(variable, true);
+           	}
+			
+			variable.scaleShownPropertyOuter.set(!variable.scaleShownPropertyOuter.get());
+			
+			if(variable.scaleShownPropertyOuter.get()) {
+				variable.scaleShownPropertyOuter.addListener(new InvalidationListener() {
+					@Override
+					public void invalidated(Observable observable) {
+						markVariable(variable, SpreadsheetCell.CornerPosition.BOTTOM_LEFT, false);
+						variable.scaleShownPropertyOuter.removeListener(this);
+					}
+				});
+			}
+		}
+	}
+	
+	public void showOnLegend(DataVariable variable) {
+		if(variable != null) {
+	        markVariable(variable, SpreadsheetCell.CornerPosition.TOP_RIGHT, !variable.legendShownProperty.get());
+
+			VisBody collection = variable.getCollection();
+			((VisCollection)collection).showVariableOnLegend(variable);
+			
+			variable.legendShownProperty.set(!variable.legendShownProperty.get());			
+		}
+	}
+	
+	public void showOnNode(DataVariable variable) {
+		if(variable != null) {        			
+	        markVariable(variable, SpreadsheetCell.CornerPosition.BOTTOM_RIGHT, !variable.nodeShownProperty.get());
+			variable.nodeShownProperty.set(!variable.nodeShownProperty.get());		
+	        
+			if(variable.isWeight() && variable.getCollection() instanceof LineConnectedCollection) {
+				((LineConnectedCollection)variable.getCollection()).showLabels(variable);
+			} else {
+	            for(int i=0; i < variable.getLength(); ++i) {
+	            	for(int j = 0; j < variable.getWidth(); ++j) {
+	            		Property property = variable.getProperty(i,j);
+	            		if(property.getBean() instanceof Mark) {
+	            			((Mark)property.getBean()).showLabel(variable, property);
+	            		}
+	            	}
+	            }				
+			}
+		}
+	}
+	
+	
+    /**
+     * Create a menu on rightClick with two options: Copy/Paste This can be
+     * overridden by developers for custom behavior.
+     * 
+     * @return the ContextMenu to use.
+     */
+    public ContextMenu getSpreadsheetViewContextMenu() {
+        final ContextMenu contextMenu = new ContextMenu();
+        
+        showAxis = new MenuItem(localize(asKey("spreadsheet.view.menu.axis")));
+        showAxis.setGraphic(new ImageView(new Image(Spreadsheet.class.getResourceAsStream("NumberAxis.png"))));
+        showAxis.setAccelerator(new KeyCodeCombination(KeyCode.A, KeyCombination.SHORTCUT_DOWN));
+        showAxis.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent e) {
+                showOnGraph();
+            }
+        });
+        
+        showParentAxis = new MenuItem(localize(asKey("spreadsheet.view.menu.parentaxis")));
+        showParentAxis.setGraphic(new ImageView(new Image(Spreadsheet.class.getResourceAsStream("NumberAxis.png"))));
+        showParentAxis.setAccelerator(new KeyCodeCombination(KeyCode.E, KeyCombination.SHORTCUT_DOWN));
+        showParentAxis.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent e) {
+                showOnParentGraph();
+            }
+        });
+        
+        showLegend = new MenuItem(localize(asKey("spreadsheet.view.menu.legend")));
+        showLegend.setGraphic(new ImageView(new Image(Spreadsheet.class.getResourceAsStream("legend.png"))));
+        showLegend.setAccelerator(new KeyCodeCombination(KeyCode.L, KeyCombination.SHORTCUT_DOWN));
+        showLegend.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent e) {
+                showOnLegend();
+            }
+        });
+        
+        showNode = new MenuItem(localize(asKey("spreadsheet.view.menu.node")));
+        showNode.setGraphic(new ImageView(new Image(Spreadsheet.class.getResourceAsStream("legend.png"))));
+        showNode.setAccelerator(new KeyCodeCombination(KeyCode.N, KeyCombination.SHORTCUT_DOWN));
+        showNode.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent e) {
+                showOnNode();
+            }
+        });
+        
+              
+        final MenuItem copyItem = new MenuItem(localize(asKey("spreadsheet.view.menu.copy"))); //$NON-NLS-1$
+        copyItem.setGraphic(new ImageView(new Image(SpreadsheetView.class
+                .getResourceAsStream("copySpreadsheetView.png")))); //$NON-NLS-1$
+        copyItem.setAccelerator(new KeyCodeCombination(KeyCode.C, KeyCombination.SHORTCUT_DOWN));
+        copyItem.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent e) {
+                copyClipboard();
+            }
+        });
+
+        final MenuItem pasteItem = new MenuItem(localize(asKey("spreadsheet.view.menu.paste"))); //$NON-NLS-1$
+        pasteItem.setGraphic(new ImageView(new Image(SpreadsheetView.class
+                .getResourceAsStream("pasteSpreadsheetView.png")))); //$NON-NLS-1$
+        pasteItem.setAccelerator(new KeyCodeCombination(KeyCode.V, KeyCombination.SHORTCUT_DOWN));
+        pasteItem.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent e) {
+                pasteClipboard();
+            }
+        });
+        
+        final Menu cornerMenu = new Menu(localize(asKey("spreadsheet.view.menu.comment"))); //$NON-NLS-1$
+        cornerMenu.setGraphic(new ImageView(new Image(SpreadsheetView.class
+                .getResourceAsStream("comment.png")))); //$NON-NLS-1$
+
+        final MenuItem topLeftItem = new MenuItem(localize(asKey("spreadsheet.view.menu.comment.top-left"))); //$NON-NLS-1$
+        topLeftItem.setOnAction(new EventHandler<ActionEvent>() {
+
+            @Override
+            public void handle(ActionEvent t) {
+                TablePosition<ObservableList<SpreadsheetCell>, ?> pos = cellsView.getFocusModel().getFocusedCell();
+                SpreadsheetCell cell = getGrid().getRows().get(pos.getRow()).get(pos.getColumn());
+                if(cell.isCornerActivated(SpreadsheetCell.CornerPosition.TOP_LEFT)) 
+                	cell.deactivateCorner(SpreadsheetCell.CornerPosition.TOP_LEFT);
+                else cell.activateCorner(SpreadsheetCell.CornerPosition.TOP_LEFT);
+                
+                }
+        });
+        final MenuItem topRightItem = new MenuItem(localize(asKey("spreadsheet.view.menu.comment.top-right"))); //$NON-NLS-1$
+        topRightItem.setOnAction(new EventHandler<ActionEvent>() {
+
+            @Override
+            public void handle(ActionEvent t) {
+                TablePosition<ObservableList<SpreadsheetCell>, ?> pos = cellsView.getFocusModel().getFocusedCell();
+                SpreadsheetCell cell = getGrid().getRows().get(pos.getRow()).get(pos.getColumn());
+                if(cell.isCornerActivated(SpreadsheetCell.CornerPosition.TOP_RIGHT)) 
+                	cell.deactivateCorner(SpreadsheetCell.CornerPosition.TOP_RIGHT);
+                else cell.activateCorner(SpreadsheetCell.CornerPosition.TOP_RIGHT);
+            }
+        });
+        final MenuItem bottomRightItem = new MenuItem(localize(asKey("spreadsheet.view.menu.comment.bottom-right"))); //$NON-NLS-1$
+        bottomRightItem.setOnAction(new EventHandler<ActionEvent>() {
+
+            @Override
+            public void handle(ActionEvent t) {
+                TablePosition<ObservableList<SpreadsheetCell>, ?> pos = cellsView.getFocusModel().getFocusedCell();
+                SpreadsheetCell cell = getGrid().getRows().get(pos.getRow()).get(pos.getColumn());
+                if(cell.isCornerActivated(SpreadsheetCell.CornerPosition.BOTTOM_RIGHT)) 
+                	cell.deactivateCorner(SpreadsheetCell.CornerPosition.BOTTOM_RIGHT);
+                else cell.activateCorner(SpreadsheetCell.CornerPosition.BOTTOM_RIGHT);
+            }
+        });
+        final MenuItem bottomLeftItem = new MenuItem(localize(asKey("spreadsheet.view.menu.comment.bottom-left"))); //$NON-NLS-1$
+        bottomLeftItem.setOnAction(new EventHandler<ActionEvent>() {
+
+            @Override
+            public void handle(ActionEvent t) {
+                TablePosition<ObservableList<SpreadsheetCell>, ?> pos = cellsView.getFocusModel().getFocusedCell();
+                SpreadsheetCell cell = getGrid().getRows().get(pos.getRow()).get(pos.getColumn());
+                if(cell.isCornerActivated(SpreadsheetCell.CornerPosition.BOTTOM_LEFT)) 
+                	cell.deactivateCorner(SpreadsheetCell.CornerPosition.BOTTOM_LEFT);
+                else cell.activateCorner(SpreadsheetCell.CornerPosition.BOTTOM_LEFT);
+            }
+        });
+
+        // I use corner annotations for marking visualized variables
+      //  cornerMenu.getItems().addAll(topLeftItem, topRightItem, bottomRightItem, bottomLeftItem);
+        
+        contextMenu.getItems().addAll(showAxis, showParentAxis, showLegend, showNode, copyItem, pasteItem /*, cornerMenu*/);
+        return contextMenu;
+    }
+
+
+	public void clean() {
+		interactor.reset();
+	}
+
+	public void update() {
+		interactor.update();
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/SpreadsheetArea.java b/src/fr/inria/structgraphics/ui/spreadsheet/SpreadsheetArea.java
new file mode 100644
index 0000000000000000000000000000000000000000..78d464b5db76ac21d79ca034b9ab7b7d5e8ddef7
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/SpreadsheetArea.java
@@ -0,0 +1,319 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.controlsfx.control.spreadsheet.Grid;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.ColorProperty;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.Draggable;
+import fr.inria.structgraphics.ui.Draggable.Type;
+import fr.inria.structgraphics.ui.viscanvas.groupings.PropertyStructure;
+import impl.org.controlsfx.spreadsheet.CellView;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ListProperty;
+import javafx.beans.property.Property;
+import javafx.scene.paint.Paint;
+
+public class SpreadsheetArea {
+	private int x, y, w, h;
+	
+	private Spreadsheet sheet;
+	private AreaContent content;
+	
+	private AreaSourceInfo info;
+	
+	public SpreadsheetArea(Spreadsheet sheet, int x, int y, int w, int h) {
+		this.x = x;
+		this.y = y;
+		this.w = w;
+		this.h = h;
+		
+		this.sheet = sheet;
+	}
+	
+	public SpreadsheetArea(Spreadsheet sheet, CellView cellView, int w, int h) {
+		this(sheet, cellView.getIndex(), Spreadsheet.toColumnIndex(cellView), w, h);
+	}
+	
+	public void dragEnded() {		
+		for(int row = x; row < x + w; ++row) {
+			for(int column = y; column < y + h; ++column) {
+				sheet.getCell(row, column).recoverStyle();
+			}	
+		}
+	}
+
+	public void updateDrag(CellView cellView) {
+		int x_ =  cellView.getIndex();
+		int y_ = Spreadsheet.toColumnIndex(cellView);
+		Grid grid = sheet.getGrid();
+
+		for(int i = Math.min(x, x_); i <  Math.max(x, x_) + w && i < grid.getRowCount(); ++i) {
+			for(int j = Math.min(y, y_); j <  Math.max(y, y_) + h && j < grid.getColumnCount(); ++j) {				
+				if(i >= x_ && i < x_ + w && j >= y_ && j < y_ + h) {
+					SpreadsheetCellAdaptable cell = sheet.getCell(i, j);
+					cell.saveStyle();
+					cell.setStyle("-fx-background-color: #eeff66;");	
+				}
+				else {
+					sheet.getCell(i, j).recoverStyle();
+				}
+			}
+		}
+		
+		x = x_;
+		y = y_;
+
+	}
+	
+	public int getStartRow() {
+		return x;
+	}
+
+	public int getStartColumn() {
+		return y;
+	}
+	
+	public int nrows() {
+		return h;
+	}
+	
+	public int ncolumns() {
+		return w;
+	}
+	
+	public DataVariable getVariable(int row, int column) {
+		return content.getVariable(row, column);
+	}
+	
+	public int getVIndex(DataVariable variable, int column) {
+		return content.getVIndex(variable, column);
+	}
+
+	public boolean contains(int row, int column) {
+		if(row >= x && row < row + h && column >= y && column < y + w) return true;
+		else return false;
+	}
+	
+	public void update(CellView cellView) {
+		x = cellView.getIndex();
+		y = Spreadsheet.toColumnIndex(cellView);
+	}
+
+	
+	public void setContent(Draggable draggable) {		
+		info = new AreaSourceInfo(draggable);
+		refresh();
+	}
+
+	public void setInfo(AreaSourceInfo info) {
+		this.info = info;
+		refresh();
+	}
+	
+	
+	public void clearSketcherLabels() {
+		for(DataVariable variable : content.getVariables()) {
+			if(variable.scaleShownProperty.get()) sheet.showOnGraph(variable);
+			if(variable.scaleShownPropertyOuter.get()) sheet.showOnParentGraph(variable);
+			if(variable.legendShownProperty.get()) sheet.showOnLegend(variable);
+			if(variable.nodeShownProperty.get()) sheet.showOnNode(variable);
+		}
+	}
+	
+	public void clear() {
+		for(int row = x; row < x + h + 1; ++row) {
+			for(int column = y; column < y + w; ++column) {
+				sheet.clear(row, column);	
+			}	
+		}
+	}
+	
+	public Type getType() {
+		return info.getType();
+	}
+	
+	public boolean refresh() {
+		if(!info.sourceExists()) {
+			info = null;
+			return false;
+		}
+		
+		switch(info.getType()) {
+			case Value:
+				if(content != null) return true;
+				
+				VisBody visbody = info.getVisBody();
+				
+				final Property property = info.getProperty();
+				DataVariable variable = new VectorVariable(visbody, x, y, property);
+				content = new AreaContent(property.getName(), variable);
+
+				///////////////////////////
+				sheet.setCellLabel(x, y, 0, variable);	
+				sheet.setCellValues(x + 1, y, variable);
+				
+				variable.setInvalidationListener(new InvalidationListener() {
+					@Override
+					public void invalidated(Observable observable) {
+						Object val = property.getValue(); 
+						if(property instanceof DoubleProperty) ((DoubleProperty)property).setValue((Number)val);
+						else if(property instanceof ColorProperty) ((ColorProperty)property).setValue((Paint)val);
+						else property.setValue(val);
+					}
+				});
+				
+				return true;
+			
+			case Column:			
+			case Table:
+				if(content == null) content = new AreaContent();
+				
+				visbody = info.getVisBody();
+				Map<PropertyName, FlexibleListProperty> propertiesMap = null;
+				
+				/// TODO: This needs more work, no?
+				if(info.isNetwork) {
+					propertiesMap = ((LineConnectedCollection)visbody).getFlowConnections().getCompactVariableList(info.getNames());
+				} else {
+					PropertyStructure structure = visbody.getChildPropertyStructure();
+					propertiesMap = info.isWide() ? structure.getVariableList(info.getNames()) : structure.getFullVariableList(info.getNames());					
+				}
+
+			// TODO: UPdata the properties within the variables!!!!			
+				int j = 0;
+				int rows = 0;
+				for(FlexibleListProperty col: propertiesMap.values()) {
+					variable = content.getVariable(col.getName());
+					
+					if(!info.isWide()) {
+						if(variable == null) {
+							variable = new ColumnVariable(visbody, x, y + j, col);
+							content.addVariable(col.getName(), variable);
+						} else {
+							variable.updatePosition(x, y + j);
+							((ColumnVariable)variable).updateProperties(col);
+							variable.transformation.get().refresh();
+						}
+						
+						sheet.setCellLabel(x, y + j, 0, variable);
+						sheet.setCellValues(x + 1, y + j, variable);
+						j++;
+						rows = Math.max(rows, variable.getLength());
+						
+					} else {
+						if(variable == null) {
+							variable = new MultiColumnVariable(visbody, x, y + j, col);
+							content.addVariable(col.getName(), variable);
+						} else {
+							variable.updatePosition(x, y + j);
+							((MultiColumnVariable)variable).updateProperties(col);
+							variable.transformation.get().refresh();
+						}
+												
+						for(int k = 0; k < variable.getWidth(); ++k) {
+							sheet.setCellLabel(x, y + j + k, k, variable);							
+						}
+						
+						// This is just to handle flow the names of connection ids
+						if(info.isNetwork && variable.isID()) {
+							((MultiColumnVariable)variable).setConnectionId();
+							sheet.setCellLabel(x, y + j, "source");
+							sheet.setCellLabel(x, y + j + 1, "destination");
+						}
+
+						sheet.setCellValues(x + 1, y + j, variable);
+						j+=variable.getWidth();
+						rows = Math.max(rows, variable.getLength());
+					}
+					
+					
+					variable.setInvalidationListener(new InvalidationListener() {
+						@Override
+						public void invalidated(Observable observable) {
+							for(Property prop: col) {
+								if(prop instanceof ListProperty) {
+									ListProperty<Property> list = (ListProperty<Property>)prop;
+									for(Property prop_: list) {
+										// TODO: an uggly way to enforce the property change!!!!!
+										Object val = prop_.getValue(); 
+										if(prop_ instanceof DoubleProperty) ((DoubleProperty)prop_).setValue((Number)val);
+										else if(prop_ instanceof ColorProperty) ((ColorProperty)prop_).setValue((Paint)val);
+										else prop_.setValue(val);
+									}
+								} else {
+									// TODO: an uggly way to enforce the property change!!!!!
+									Object val = prop.getValue(); 
+									if(prop instanceof DoubleProperty) ((DoubleProperty)prop).setValue((Number)val);
+									else if(prop instanceof ColorProperty) ((ColorProperty)prop).setValue((Paint)val);
+									else prop.setValue(val);
+								}
+							}
+						}
+					});
+					
+					// Update Labels on Nodes
+					for(Property prop: col) {
+						if(prop instanceof ListProperty) {
+							ListProperty<Property> list = (ListProperty<Property>)prop;
+							for(Property prop_: list) {
+			            		if(prop_.getBean() instanceof ShapeMark) {
+			            			ShapeMark mark = (ShapeMark)prop_.getBean();
+			            			if(variable.nodeShownProperty.get() && !mark.isLabelShown(variable))
+			            				mark.showLabel(variable, prop_);
+			            		}
+							}
+						} else {
+		            		if(prop.getBean() instanceof ShapeMark) {
+		            			ShapeMark mark = (ShapeMark)prop.getBean();
+		            			if(variable.nodeShownProperty.get() && !mark.isLabelShown(variable))
+		            				mark.showLabel(variable, prop);
+		            		}
+						}
+					}
+					
+				}
+				
+				w = j;
+				h = rows;
+				
+				return true;
+		}		
+		
+		return false;
+	}
+
+	
+	public Container getSource() {
+		return info.source;
+	}
+	
+	public VisBody getVisBody() {
+		return info.visbody;
+	}
+	
+	public boolean isWide() {
+		return info.wide;
+	}
+	
+	public boolean isNetwork() {
+		return info.isNetwork;
+	}
+	
+	public ArrayList<PropertyName> getPropertyNames() {
+		return info.names;
+	}
+
+	public AreaContent getAreaContent() {
+		return content;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/SpreadsheetCellAdaptable.java b/src/fr/inria/structgraphics/ui/spreadsheet/SpreadsheetCellAdaptable.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c5ce711dd4fe7fb1b5cb1c76ccde366997d1a29
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/SpreadsheetCellAdaptable.java
@@ -0,0 +1,696 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import com.sun.javafx.event.EventHandlerManager;
+
+import impl.org.controlsfx.spreadsheet.CellView;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetCellType;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.ReadOnlyStringProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableSet;
+import javafx.event.Event;
+import javafx.event.EventDispatchChain;
+import javafx.event.EventHandler;
+import javafx.event.EventTarget;
+import javafx.event.EventType;
+import javafx.scene.Node;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.input.PickResult;
+
+/**
+ * The SpreadsheetCells serve as model for the {@link SpreadsheetView}. <br>
+ * You will provide them when constructing a {@link Grid}.
+ * 
+ * <br>
+ * <h3>SpreadsheetCell Types</h3> Each SpreadsheetCell has its own
+ * {@link SpreadsheetCellType} which has its own {@link SpreadsheetCellEditor}
+ * in order to control very closely the possible modifications.
+ * 
+ * <p>
+ * Different {@link SpreadsheetCellType SpreadsheetCellTypes} are available
+ * depending on the data you want to represent in your {@link SpreadsheetView}.
+ * You can use the different static method provided in
+ * {@link SpreadsheetCellType} in order to create the specialized
+ * SpreadsheetCell that suits your need.
+ * 
+ * 
+ * <br>
+ * 
+ * <p>
+ * If you want to create a SpreadsheetCell of your own, you simply have to
+ * use one of the provided constructor. Usually you will let your {@link SpreadsheetCellType}
+ * create the cells. For example 
+ * {@link SpreadsheetCellType.StringType#createCell(int, int, int, int, java.lang.String) }.
+ * You will also have to provide a custom {@link SpreadsheetCellEditor}.
+ * 
+ * <h2>Configuration</h2>
+ * You will have to indicate the coordinates of the cell together with the
+ * {@link #setRowSpan(int) row} and {@link #setColumnSpan(int) column} span. You
+ * can specify if you want the cell to be editable or not using
+ * {@link #setEditable(boolean)}. Be advised that a cell with a rowSpan means
+ * that the cell will replace all the cells situated in the rowSpan range. Same
+ * with the column span. 
+ * <br>
+ * So the best way to handle spanning is to fill your grid
+ * with unique cells, and then call at the end {@link GridBase#spanColumn(int, int, int)}
+ * or {@link GridBase#spanRow(int, int, int)}. These methods will handle the span
+ * for you.
+ * 
+ * <br>
+ * 
+ * <h3>Format</h3>
+ * Your cell can have its very own format. If you want to display some dates
+ * with different format, you just have to create a unique
+ * {@link SpreadsheetCellType} and then specify for each cell their format with
+ * {@link #setFormat(String)}. You will then have the guaranty that all your
+ * cells will have a LocalDate as a value, but the value will be displayed
+ * differently for each cell. This will also guaranty that copy/paste and other
+ * operation will be compatible since every cell will share the same
+ * {@link SpreadsheetCellType}. <br>
+ * Here an example : <br>
+ * 
+ * 
+ * <pre>
+ * SpreadsheetCell cell = SpreadsheetCellType.DATE.createCell(row, column, rowSpan, colSpan,
+ *         LocalDate.now().plusDays((int) (Math.random() * 10))); // Random value
+ * // given here
+ * final double random = Math.random();
+ * if (random &lt; 0.25) {
+ *     cell.setFormat(&quot;EEEE d&quot;);
+ * } else if (random &lt; 0.5) {
+ *     cell.setFormat(&quot;dd/MM :YY&quot;);
+ * } else {
+ *     cell.setFormat(&quot;dd/MM/YYYY&quot;);
+ * }
+ * </pre>
+ * 
+ * <center><img src="dateFormat.PNG" alt="SpreadsheetCellBase with custom format"></center>
+ * 
+ * <h3>Graphic</h3>
+ * Each cell can have a graphic to display next to the text in the cells. Just
+ * use the {@link #setGraphic(Node)} in order to specify the graphic you want.
+ * If you specify an {@link ImageView}, the SpreadsheetView will try to resize it in
+ * order to fit the space available in the cell.
+ * 
+ * For example :
+ * 
+ * <pre>
+ * cell.setGraphic(new ImageView(new Image(getClass().getResourceAsStream(&quot;icons/exclamation.png&quot;))));
+ * </pre>
+ * 
+ * <center><img src="graphicNodeToCell.png" alt="SpreadsheetCellBase with graphic"></center> <br>
+ * In addition to that, you can also specify another graphic property to your
+ * cell with {@link #activateCorner(org.controlsfx.control.spreadsheet.SpreadsheetCell.CornerPosition) }.
+ * This allow you to activate or deactivate some graphics on the cell in every 
+ * corner. Right now it's a little red triangle but you can modify this in your CSS by
+ * using the "<b>cell-corner</b>" style class.
+ * 
+ * <pre>
+ * .cell-corner.top-left{
+ *     -fx-background-color: red;
+ *     -fx-shape : "M 0 0 L 1 0 L 0 1 z";
+ * }
+ * </pre>
+ * 
+ * <center><img src="triangleCell.PNG" alt="SpreadsheetCellBase with a styled cell-corner"></center>
+ * 
+ * 
+ * <br>
+ * You can also customize the tooltip of your SpreadsheetCell by specifying one
+ * with {@link #setTooltip(java.lang.String) }.
+ * 
+ * <h3>Style with CSS</h3>
+ * You can style your cell by specifying some styleClass with
+ * {@link #getStyleClass()}. You just have to create and custom that class in
+ * your CSS stylesheet associated with your {@link SpreadsheetView}. Also note
+ * that all {@link SpreadsheetCell} have a "<b>spreadsheet-cell</b>" styleClass
+ * added by default. Here is a example :<br>
+ * 
+ * <pre>
+ * cell.getStyleClass().add(&quot;row_header&quot;);
+ * </pre>
+ * 
+ * And in the CSS:
+ * 
+ * <pre>
+ *  .spreadsheet-cell.row_header{
+ *     -fx-background-color: #b4d4ad ;
+ *     -fx-background-insets: 0, 0 1 1 0;
+ *     -fx-alignment: center;
+ * }
+ * </pre>
+ * 
+ * <h3>Examples</h3>
+ * Here is an example that uses all the pre-built {@link SpreadsheetCellType}
+ * types. The generation is random here so you will want to replace the logic to
+ * suit your needs.
+ * 
+ * <pre>
+ * private SpreadsheetCell&lt;?&gt; generateCell(int row, int column, int rowSpan, int colSpan) {
+ *     List&lt;String&gt; stringListTextCell = Arrays.asList("Shanghai","Paris","New York City","Bangkok","Singapore","Johannesburg","Berlin","Wellington","London","Montreal");
+ *     final double random = Math.random();
+ *     if (random &lt; 0.10) {
+ *         List&lt;String&gt; stringList = Arrays.asList("China","France","New Zealand","United States","Germany","Canada");
+ *         cell = SpreadsheetCellType.LIST(stringList).createCell(row, column, rowSpan, colSpan, stringList.get((int) (Math.random() * 6)));
+ *     } else if (random &gt;= 0.10 &amp;&amp; random &lt; 0.25) {
+ *         cell = SpreadsheetCellType.STRING.createCell(row, column, rowSpan, colSpan,stringListTextCell.get((int)(Math.random()*10)));
+ *     } else if (random &gt;= 0.25 &amp;&amp; random &lt; 0.75) {
+ *         cell = SpreadsheetCellType.DOUBLE.createCell(row, column, rowSpan, colSpan,(double)Math.round((Math.random()*100)*100)/100);
+ *     } else {
+ *         cell = SpreadsheetCellType.DATE.createCell(row, column, rowSpan, colSpan, LocalDate.now().plusDays((int)(Math.random()*10)));
+ *     }
+ *     return cell;
+ * }
+ * </pre>
+ * 
+ * @see SpreadsheetView
+ * @see SpreadsheetCellEditor
+ * @see SpreadsheetCellType
+ */
+public class SpreadsheetCellAdaptable implements SpreadsheetCell, EventTarget{
+
+    /***************************************************************************
+     * 
+     * Private Fields
+     * 
+     **************************************************************************/
+
+    //The Bit position for the editable Property.
+    private static final int EDITABLE_BIT_POSITION = 4;
+    private static final int WRAP_BIT_POSITION = 5;
+    private  SpreadsheetCellType type;
+    private final int row;
+    private final int column;
+    private int rowSpan;
+    private int columnSpan;
+    private final StringProperty format;
+    private final StringProperty text;
+    private final StringProperty styleProperty;
+    private final ObjectProperty<Node> graphic;
+    private String tooltip;
+    /**
+     * This variable handles all boolean values of this SpreadsheetCell inside
+     * its bits. Instead of using regular boolean, we use that int so that we 
+     * can reduce memory usage to the bare minimum.
+     */
+    private int propertyContainer = 0;
+    private final EventHandlerManager eventHandlerManager = new EventHandlerManager(this);
+
+    private ObservableSet<String> styleClass;
+
+    // Added by Theophanis Tsandilas
+    private /*ChangeListener*/ InvalidationListener changeListener = null; // Listener that updates the property when the cell changes
+    private Property property; // Property to which the cell is linked
+    private InvalidationListener propertyListener = null; // Listener that updates the cell when the property changes
+    
+    
+    /***************************************************************************
+     * 
+     * Constructor
+     * 
+     **************************************************************************/
+
+    /**
+     * Constructs a SpreadsheetCell with the given configuration.
+     * Use the {@link SpreadsheetCellType#OBJECT} type.
+     * @param row
+     * @param column
+     * @param rowSpan
+     * @param columnSpan
+     */
+    public SpreadsheetCellAdaptable(final int row, final int column, final int rowSpan, final int columnSpan) {
+        this(row, column, rowSpan, columnSpan, SpreadsheetCellType.OBJECT);
+    }
+
+    /**
+     * Constructs a SpreadsheetCell with the given configuration.
+     * 
+     * @param row
+     * @param column
+     * @param rowSpan
+     * @param columnSpan
+     * @param type
+     */
+    public SpreadsheetCellAdaptable(final int row, final int column, final int rowSpan, final int columnSpan,
+            final SpreadsheetCellType<?> type) {
+        this.row = row;
+        this.column = column;
+        this.rowSpan = rowSpan;
+        this.columnSpan = columnSpan;
+        this.type = type;
+        text = new SimpleStringProperty(""); //$NON-NLS-1$
+        format = new SimpleStringProperty(""); //$NON-NLS-1$
+        graphic = new SimpleObjectProperty<>();
+        format.addListener(new ChangeListener<String>() {
+            @Override
+            public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) {            	
+                updateText();
+            }
+        });
+        //Editable is true at the initialisation
+        setEditable(true);
+        getStyleClass().add("spreadsheet-cell"); //$NON-NLS-1$
+        styleProperty = new SimpleStringProperty();
+        
+    }
+    
+    
+    public void setType(SpreadsheetCellType<?> type) {
+    	this.type = type;
+    }
+
+   /***************************************************************************
+     * 
+     * Public Methods
+     * 
+     **************************************************************************/
+    
+    /** {@inheritDoc} */
+    @Override
+    public boolean match(SpreadsheetCell cell) {
+        return type.match(cell);
+    }
+
+    // --- item
+    private final ObjectProperty<Object> item = new SimpleObjectProperty<Object>(this, "item") { //$NON-NLS-1$
+        @Override
+        protected void invalidated() {        	
+            updateText();
+        }
+    };
+
+   /** {@inheritDoc} */
+    @Override
+    public final void setItem(Object value) {
+        if (isEditable())
+            item.set(value);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final Object getItem() {
+        return item.get();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final ObjectProperty<Object> itemProperty() {
+        return item;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final boolean isEditable() {
+        return isSet(EDITABLE_BIT_POSITION);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void setEditable(boolean editable) {
+        if(setMask(editable, EDITABLE_BIT_POSITION)){
+            Event.fireEvent(this, new Event(EDITABLE_EVENT_TYPE));
+        }
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public boolean isWrapText(){
+        return isSet(WRAP_BIT_POSITION);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setWrapText(boolean wrapText) {
+        if (setMask(wrapText, WRAP_BIT_POSITION)) {
+            Event.fireEvent(this, new Event(WRAP_EVENT_TYPE));
+        }
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public final StringProperty formatProperty() {
+        return format;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final String getFormat() {
+        return format.get();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void setFormat(String format) {
+        formatProperty().set(format);
+        updateText();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final ReadOnlyStringProperty textProperty() {
+        return text;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final String getText() {
+        return text.get();
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public final SpreadsheetCellType getCellType() {
+        return type;
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public final int getRow() {
+        return row;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final int getColumn() {
+        return column;
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public final int getRowSpan() {
+        return rowSpan;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void setRowSpan(int rowSpan) {
+        this.rowSpan = rowSpan;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final int getColumnSpan() {
+        return columnSpan;
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public final void setColumnSpan(int columnSpan) {
+        this.columnSpan = columnSpan;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final ObservableSet<String> getStyleClass() {
+        if (styleClass == null) {
+            styleClass = FXCollections.observableSet();
+        }
+        return styleClass;
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public void setStyle(String style){
+        styleProperty.set(style);
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public String getStyle(){
+        return styleProperty.get();
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public StringProperty styleProperty(){
+        return styleProperty;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public ObjectProperty<Node> graphicProperty() {
+        return graphic;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setGraphic(Node graphic) {
+        this.graphic.set(graphic);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Node getGraphic() {
+        return graphic.get();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Optional<String> getTooltip() {
+        return Optional.ofNullable(tooltip);
+    }
+    
+    /**
+     * Set a new tooltip for this cell.
+     * @param tooltip 
+     */
+    public void setTooltip(String tooltip){
+        this.tooltip = tooltip;
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public void activateCorner(CornerPosition position) {
+        if(setMask(true, getCornerBitNumber(position))){
+            Event.fireEvent(this, new Event(CORNER_EVENT_TYPE));
+        }
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public void deactivateCorner(CornerPosition position) {
+        if(setMask(false, getCornerBitNumber(position))){
+             Event.fireEvent(this, new Event(CORNER_EVENT_TYPE));
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isCornerActivated(CornerPosition position) {
+        return isSet(getCornerBitNumber(position));
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public EventDispatchChain buildEventDispatchChain(EventDispatchChain tail) {
+        return tail.append(eventHandlerManager);
+    }
+    
+    /***************************************************************************
+     * 
+     * Overridden Methods
+     * 
+     **************************************************************************/
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return "cell[" + row + "][" + column + "]" + rowSpan + "-" + columnSpan; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!(obj instanceof SpreadsheetCell))
+            return false;
+
+        final SpreadsheetCell otherCell = (SpreadsheetCell) obj;
+        return otherCell.getRow() == row && otherCell.getColumn() == column
+                && Objects.equals(otherCell.getText(), getText())
+                && rowSpan == otherCell.getRowSpan()
+                && columnSpan == otherCell.getColumnSpan()
+                && Objects.equals(getStyleClass(), otherCell.getStyleClass());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + column;
+        result = prime * result + row;
+        result = prime * result + rowSpan;
+        result = prime * result + columnSpan;
+        result = prime * result + Objects.hashCode(getText());
+        result = prime * result + Objects.hashCode(getStyleClass());
+        return result;
+    }
+    
+    /**
+     * Registers an event handler to this SpreadsheetCell. The SpreadsheetCell class allows 
+     * registration of listeners which will be notified when a corner state of
+     * the editable state of this SpreadsheetCell have changed.
+     *
+     * @param eventType the type of the events to receive by the handler
+     * @param eventHandler the handler to register
+     * @throws NullPointerException if the event type or handler is null
+     */
+    @Override
+    public void addEventHandler(EventType<Event> eventType, EventHandler<Event> eventHandler) {
+         eventHandlerManager.addEventHandler(eventType, eventHandler);
+    }
+
+    /**
+     * Unregisters a previously registered event handler from this SpreadsheetCell. One
+     * handler might have been registered for different event types, so the
+     * caller needs to specify the particular event type from which to
+     * unregister the handler.
+     *
+     * @param eventType the event type from which to unregister
+     * @param eventHandler the handler to unregister
+     * @throws NullPointerException if the event type or handler is null
+     */
+    @Override
+    public void removeEventHandler(EventType<Event> eventType, EventHandler<Event> eventHandler) {
+         eventHandlerManager.removeEventHandler(eventType, eventHandler);
+    }
+    
+    /***************************************************************************
+     * 
+     * Private Implementation
+     * 
+     **************************************************************************/
+
+    /**
+     * Update the text for the SpreadsheetView.
+     */
+    @SuppressWarnings("unchecked")
+    private void updateText() {
+        if(getItem() == null){
+            text.setValue(""); //$NON-NLS-1$
+        }else if (!("").equals(getFormat())) { //$NON-NLS-1$
+            text.setValue(type.toString(getItem(), getFormat()));
+        } else {
+            text.setValue(type.toString(getItem()));
+        }
+    }
+
+    /**
+     * Return the Bit position for each corner.
+     * @param position
+     * @return 
+     */
+    private int getCornerBitNumber(CornerPosition position) {
+        switch (position) {
+            case TOP_LEFT:
+                return 0;
+
+            case TOP_RIGHT:
+                return 1;
+
+            case BOTTOM_RIGHT:
+                return 2;
+
+            case BOTTOM_LEFT:
+            default:
+                return 3;
+        }
+    }
+
+    /**
+     * Set the specified bit position at the value specified by flag.
+     * @param flag
+     * @param position
+     * @return whether a change has really occured.
+     */
+    private boolean setMask(boolean flag, int position) {
+        int oldCorner = propertyContainer;
+        if (flag) {
+            propertyContainer |= (1 << position);
+        } else {
+            propertyContainer &= ~(1 << position);
+        }
+        return propertyContainer != oldCorner;
+    }
+
+    /**
+     * @param mask
+     * @param position
+     * @return whether the specified bit position is true.
+     */
+    private boolean isSet(int position) {
+        return (propertyContainer & (1 << position)) != 0;
+    }
+
+    private boolean saved = false;
+    private String oldstyle = null;
+    
+    public void saveStyle() {
+    	if(!saved) {
+    		oldstyle = getStyle();
+    		saved = true;
+    	}
+    }
+   
+	public void recoverStyle() {
+		setStyle(oldstyle);
+		saved = false;
+	}
+
+	
+	private boolean lockProperty = false, lockCell = false;
+	
+	public void lockPropertyListener(boolean lock) {
+		lockProperty = lock;
+	}
+	
+	public boolean isPropertyListenerLocked() {
+		return lockProperty;
+	}
+	
+	public boolean isCellListenerLocked() {
+		return lockCell;
+	}
+	
+	public void lockCellListener(boolean lock) {
+		lockCell = lock;
+	}
+	
+	/*
+	public void setCellListener(ChangeListener changeListener) {
+		if(this.changeListener != null) itemProperty().removeListener(this.changeListener);
+		this.changeListener = changeListener;
+		if(changeListener != null) itemProperty().addListener(changeListener);
+	}*/
+	
+	public void setCellListener(InvalidationListener changeListener) {
+		if(this.changeListener != null) itemProperty().removeListener(this.changeListener);
+		this.changeListener = changeListener;
+		if(changeListener != null) itemProperty().addListener(changeListener);
+	}
+	
+	public void setPropertyListener(Property property, InvalidationListener listener) {
+		if(this.property != null && propertyListener != null)
+			this.property.removeListener(propertyListener);
+		
+		this.property = property;
+		this.propertyListener = listener;
+		if(listener != null && property != null) property.addListener(listener);
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/TransformationField.java b/src/fr/inria/structgraphics/ui/spreadsheet/TransformationField.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d6a2af397ce36c5b9eacad3dceb05b60dd5ccf7
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/TransformationField.java
@@ -0,0 +1,144 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable.DataType;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+
+public class TransformationField extends HBox implements ChangeListener<String> {
+
+	private DataVariable activeVariable = null;
+	private int activeIndex = 0;
+	private final static String DEFAULT_TEXT = "T(x)=";
+	
+	private ComboBox typeMenu = new ComboBox();
+	private TextField textField = new TextField();
+	private Label label;
+		
+	public TransformationField(HBox toolBar) {
+
+		typeMenu.getItems().addAll("Symbolic", "Functional");
+		typeMenu.setValue("Functional");
+		
+		typeMenu.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
+			@Override
+			public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {				
+				if(activeVariable != null && typeHasChanged(newValue)) {
+					// activeVariable.transformation.get().change.set(!activeVariable.transformation.get().change.get());
+			// TODO: This is buggy. It should not change when clicking on a different variable!!!!	
+					if(newValue.equals("Symbolic")) {
+						activeVariable.setDataType(DataType.Symbolic);
+						activeVariable.transformation.get().expression.addListener(expressionListener);
+					} else {
+						activeVariable.setDataType(DataType.Functional);
+						activeVariable.transformation.get().expression.removeListener(expressionListener);
+					}
+					
+					textField.setText(activeVariable.transformationProperty().get().getExpression().get());	
+					
+					if(activeVariable.collection instanceof VisCollection) ((VisCollection)activeVariable.collection).updateExtraComponents();
+				}
+			}
+		});
+				
+		textField.setOnKeyPressed(new EventHandler<KeyEvent>()
+	    {
+	        @Override
+	        public void handle(KeyEvent e)
+	        {
+	            if (e.getCode().equals(KeyCode.ENTER))
+	            {
+	            	activeVariable.transformationProperty().get().setExpression(textField.getText());
+	            	textField.setText(activeVariable.transformationProperty().get().getExpression().get());
+	            		
+	                label.requestFocus();
+	            }
+	        }
+	    });
+		
+		label = new Label(DEFAULT_TEXT);
+		label.setStyle("-fx-padding:5px;");
+		label.setAlignment(Pos.CENTER_RIGHT);
+		
+		//textField.setPadding(new Insets(10));
+		this.setPadding(new Insets(10));
+		
+		HBox.setHgrow(textField, Priority.ALWAYS);
+		
+		getChildren().add(toolBar);
+		getChildren().add(typeMenu);
+		getChildren().add(label);
+		getChildren().add(textField);
+		
+		disable(true);
+	}
+	
+	private boolean typeHasChanged(String value) {
+		if(value.equals("Symbolic")) {
+			 if(activeVariable.getDataType() == DataType.Functional) return true;
+			 else return false;
+		}
+		else {
+			if(activeVariable.getDataType() == DataType.Functional) return false;
+			else return true;
+		}
+	}
+	
+	public void disable(boolean disable) {
+		typeMenu.setDisable(disable);
+		label.setDisable(disable);
+		textField.setDisable(disable);
+	}
+	
+	public void setDefaultLabel() {
+		label.setText(DEFAULT_TEXT);
+		textField.setText("");
+	}
+
+	public void setVariable(DataVariable variable, int vindex) {
+		label.setText(variable.getName(vindex).get() + "=");
+		textField.setText(variable.transformationProperty().get().getExpression().get());
+		
+		if(this.activeVariable == variable) return;
+		else if(activeVariable != null) {
+			// TODO: ????
+			activeVariable.getName(activeIndex).removeListener(this);
+			activeVariable.transformation.get().expression.removeListener(expressionListener);
+		}
+		
+		activeVariable = variable;
+		activeIndex = vindex;
+		activeVariable.getName(vindex).addListener(this);
+		
+		if(variable.getDataType() == DataType.Symbolic) {
+			typeMenu.setValue("Symbolic");
+			variable.transformation.get().expression.addListener(expressionListener);
+		} else typeMenu.setValue("Functional");		
+	}
+	
+	
+	private ChangeListener expressionListener = new ChangeListener<String>() {
+		@Override
+		public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { 
+			textField.setText(activeVariable.transformationProperty().get().getExpression().get());	
+		}
+	};
+	
+	@Override
+	public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
+		label.setText(newValue + "=");	
+	}
+	
+	
+
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/VectorVariable.java b/src/fr/inria/structgraphics/ui/spreadsheet/VectorVariable.java
new file mode 100644
index 0000000000000000000000000000000000000000..b75e475f3613a8120f31920eb15394a972af4e40
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/VectorVariable.java
@@ -0,0 +1,62 @@
+package fr.inria.structgraphics.ui.spreadsheet;
+
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import javafx.beans.binding.ListExpression;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class VectorVariable extends DataVariable {
+
+	private Property property;
+	protected StringProperty name = new SimpleStringProperty();
+
+	public VectorVariable(VisBody collection, int row, int column, Property property) {
+		super(collection, row, column);
+		
+		name.set(property.getName());
+		
+		this.property =  property;
+		/*
+		if(property instanceof FlexibleListProperty) {
+			this.property = ((FlexibleListProperty) property).get(0);
+		} else this.property = property;*/
+						
+		setTransformation();
+	}
+	
+	@Override
+	public String getPropertyName() {
+		return property.getName();
+	}
+	
+	@Override
+	public StringProperty getName(int vindex) {
+		return name;
+	}
+	
+	@Override
+	public int getLength() {
+		return 1; 
+	}
+	
+	@Override
+	public int getWidth() {
+		if(property instanceof FlexibleListProperty)
+			return ((ListExpression<Property>) property).size();
+		else return 1;
+	}
+
+	@Override
+	public Property getProperty(int vindex, int hindex) {
+		if(property instanceof FlexibleListProperty)
+			return ((FlexibleListProperty)property).get(hindex);
+		else return property;
+	}
+
+	@Override
+	public boolean contains(int row, int column) {
+		return (this.column == column && row >= this.row && row <= this.row + 1);
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/legend.png b/src/fr/inria/structgraphics/ui/spreadsheet/legend.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2295711ef3a2a7fc43a934df2c0269f0d5b4f76
Binary files /dev/null and b/src/fr/inria/structgraphics/ui/spreadsheet/legend.png differ
diff --git a/src/fr/inria/structgraphics/ui/spreadsheet/spreadsheet.css b/src/fr/inria/structgraphics/ui/spreadsheet/spreadsheet.css
new file mode 100644
index 0000000000000000000000000000000000000000..828c1e001efc88473d24da0d794ba089dd26adcc
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/spreadsheet/spreadsheet.css
@@ -0,0 +1,162 @@
+.cell-spreadsheet .table-row-cell {
+    -fx-background-color: transparent;
+}
+
+/* NORMAL CELL */
+.spreadsheet-cell:filled:selected,
+.spreadsheet-cell:filled:focused:selected,
+.spreadsheet-cell:filled:focused:selected:hover {
+    -fx-background-color: #d2dff2;
+    -fx-border-color: #a9a9a9;
+    -fx-border-width : 0.5px;
+    -fx-text-fill: -fx-selection-bar-text;
+
+}
+.spreadsheet-cell:hover,
+.spreadsheet-cell:filled:focused {
+    -fx-background-color: #DFDADA;
+    -fx-text-fill: -fx-text-inner-color;
+    -fx-background-insets: 0, 0 0 1 0;
+}
+
+.spreadsheet-cell{
+    -fx-padding: 0 0 0 0.2em;
+    -fx-border-color: black;
+    -fx-border-width : 0.3px;
+    -fx-background-color: -fx-table-cell-border-color,white;
+}
+
+.tooltip {
+    -fx-background-radius: 0px;
+    -fx-background-color:
+        linear-gradient(#cec340, #a59c31),
+        linear-gradient(#fefefc, #e6dd71),
+        linear-gradient(#fef592, #e5d848);
+    -fx-background-insets: 0,1,2;
+    -fx-padding: 0.333333em 0.666667em 0.333333em 0.666667em; /* 4 8 4 8 */
+    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 8, 0.0 , 0 , 0 );
+    -fx-text-fill:black;
+}
+
+/* FIXED HEADERS  */
+VerticalHeader > Label.fixed{
+    -fx-background-color: -fx-box-border, -fx-inner-border,   linear-gradient(to left, derive(-fx-color,-20%) ,derive(-fx-color,-10%));
+    -fx-font-style : italic;
+}
+
+HorizontalHeaderColumn > TableColumnHeader.column-header.table-column.fixed{
+    -fx-background-color: -fx-box-border, -fx-inner-border,   linear-gradient(to top, derive(-fx-color,-20%) ,derive(-fx-color,-10%));
+    -fx-font-style : italic;
+}
+
+/* HORIZONTAL AND VERTICAL HEADER SELECTION */
+
+/*
+VerticalHeader > Label {
+    -fx-background-color: -fx-box-border, -fx-inner-border,  linear-gradient(to left, derive(-fx-color,-5%) ,derive(-fx-color,5%));
+    -fx-background-insets: 0, 0 1 1 0, 1 2 2 1;
+    -fx-font-weight: bold;
+    -fx-size: 2em;
+    -fx-text-fill: -fx-selection-bar-text;
+    /*-fx-padding: 0.166667em;*/
+    /*-fx-label-padding:0 0 0 20;*/
+    -fx-alignment: center;
+    -fx-font-style : normal;
+} */ 
+
+VerticalHeader > Label.selected{
+    -fx-background-color: -fx-box-border, -fx-inner-border,  linear-gradient(to right, derive(#FFDB6D,-10%) ,derive(#FFDB6D,10%));
+    -fx-background-insets: 0, 0 1 1 0, 1 2 2 1;
+    -fx-font-weight: bold;
+    -fx-size: 2em;
+    -fx-text-fill: -fx-selection-bar-text;
+    -fx-alignment: center;
+    -fx-border-color : #FFDB6D;
+}
+
+/*
+HorizontalHeaderColumn > TableColumnHeader.column-header.table-column.selected{
+    -fx-background-color: -fx-box-border, -fx-inner-border,  linear-gradient(to bottom, derive(#FFDB6D,-10%) ,derive(#FFDB6D,10%));
+    -fx-background-insets: 0, 0 1 1 0, 1 2 2 1;
+    -fx-font-weight: bold;
+    -fx-size: 2em;
+    -fx-text-fill: -fx-selection-bar-text;
+    -fx-alignment: center;
+    -fx-border-color : #FFDB6D;
+} */ 
+
+/* HORIZONTAL HEADER VISIBILITY */
+.column-header-background.invisible { visibility: hidden; -fx-padding: -1em; }
+
+.cell-corner{
+    -fx-background-color: red;
+}
+
+.cell-corner.top-left{
+    -fx-shape : "M 0 0 L 1 0 L 0 1 z";
+}
+
+.cell-corner.top-right{
+    -fx-shape : "M 0 0 L -1 0 L 0 1 z";
+}
+
+.cell-corner.bottom-right{
+    -fx-shape : "M 0 0 L -1 0 L 0 -1 z";
+}
+
+.cell-corner.bottom-left{
+    -fx-shape : "M 0 0 L 1 0 L 0 -1 z";
+}
+
+.indicationLabel{
+    -fx-font-style : italic;
+}
+
+/* PICKERS */
+.picker-label{
+    -fx-graphic: url("picker.png"); 
+    -fx-background-color: white;
+    -fx-padding: 0 0 0 0;
+    -fx-alignment: center;
+}
+
+.picker-label:hover{
+    /*-fx-effect:dropshadow(gaussian, black, 10, 0.1, 0, 0);*/
+    -fx-cursor:hand;
+}
+
+/* We don't want to show the white background both for TextField
+and textArea. We want it to be transparent just like Excel.
+
+Also we need to shift to the left the editor a bit*/
+CellView > .text-input.text-field{
+    -fx-padding : 0 0 0 -0.2em;
+    -fx-background-color: transparent;
+}
+CellView > .text-input.text-area,
+CellView > TextArea .scroll-pane > .viewport{
+    -fx-background-color: transparent;
+}
+
+/* I shift by 3px, it's not clean but it works for normal row (24px) as it 
+centers the textArea.*/
+CellView > TextArea .scroll-pane{
+    -fx-padding : 3px 0 0 -0.15em;
+}
+
+CellView > TextArea .scroll-pane > .viewport .content{
+    -fx-padding : 0 0 0 0;
+    -fx-background-color: transparent;
+}
+/* The scrollBars must always have the same size because we may have
+really big font in the editor (48px) and the scrollBars become obese otherwise.*/
+CellView >TextArea .scroll-bar:vertical ,
+CellView >TextArea .scroll-bar:horizontal {
+    -fx-font-size : 1em;
+}
+
+.selection-rectangle{
+    -fx-fill : transparent;
+    -fx-stroke : black;
+    -fx-stroke-width : 2;
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/BezierDrawingTool.java b/src/fr/inria/structgraphics/ui/tools/BezierDrawingTool.java
new file mode 100644
index 0000000000000000000000000000000000000000..868f60a439ca3c9361eb038a0c8cc5888671e418
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/BezierDrawingTool.java
@@ -0,0 +1,23 @@
+package fr.inria.structgraphics.ui.tools;
+
+import fr.inria.structgraphics.ui.inspector.DisplayUtils;
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.image.ImageView;
+
+public class BezierDrawingTool extends DrawingTool {
+	
+	
+	public BezierDrawingTool(CanvasFrame canvas) {
+		super(canvas);
+	}
+	
+	@Override
+	protected void init() {
+		tbutton =  new ToggleButton("", new ImageView(DisplayUtils.getIcon("SVGPath")));
+		super.init();
+	}
+	
+}
+
+
diff --git a/src/fr/inria/structgraphics/ui/tools/CancelTranslateTransition.java b/src/fr/inria/structgraphics/ui/tools/CancelTranslateTransition.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e87d91f3d99f6e745f9310936851055dfbb1b3d
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/CancelTranslateTransition.java
@@ -0,0 +1,35 @@
+package fr.inria.structgraphics.ui.tools;
+
+import javafx.animation.Transition;
+import javafx.scene.shape.Line;
+import javafx.util.Duration;
+
+public class CancelTranslateTransition extends Transition {
+
+	private Line lineTrace;
+	private double x0, y0, x1, y1;
+	
+	private Tool tool;
+	
+	public CancelTranslateTransition(Duration duration, Tool tool) {
+		setCycleDuration(duration);
+		
+		this.lineTrace = tool.lineTrace;
+		x0 = lineTrace.getStartX();
+		y0 = lineTrace.getStartY();
+		
+		x1 = lineTrace.getEndX();
+		y1 = lineTrace.getEndY();
+		
+		this.tool = tool;		
+	}
+	
+    @Override
+    protected void interpolate(double fraction) {
+    	lineTrace.setEndX(fraction*x0 + (1 - fraction)*x1);
+    	lineTrace.setEndY(fraction*y0 + (1 - fraction)*y1);
+    	
+    	tool.update();    	
+    	if(fraction == 1) tool.cancelComplete();
+    }
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/CollectionCreationTool.java b/src/fr/inria/structgraphics/ui/tools/CollectionCreationTool.java
new file mode 100644
index 0000000000000000000000000000000000000000..5590e31fa7233f48885408b2007fb6c54823e737
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/CollectionCreationTool.java
@@ -0,0 +1,110 @@
+package fr.inria.structgraphics.ui.tools;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.ui.inspector.DisplayUtils;
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import fr.inria.structgraphics.ui.viscanvas.groupings.Grouping;
+import fr.inria.structgraphics.ui.viscanvas.groupings.Grouping.Type;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.Cursor;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+
+public class CollectionCreationTool extends Tool {
+	
+	private MarkSelection selectedMarks = new MarkSelection();
+	
+	public CollectionCreationTool(CanvasFrame canvas) {
+		super(canvas);
+				
+		traceColor = Color.BLUE;
+		traceWidth = 2;
+		
+		rectangular = true;
+	}
+	
+	@Override
+	protected void init() {
+		cursor = Cursor.DEFAULT;
+		tbutton =  new ToggleButton("", new ImageView(DisplayUtils.getIcon("link")));
+		//tbutton =  new ToggleButton("", new ImageView(DisplayUtils.getIcon("BarChart")));
+		
+		super.init();
+	}
+	
+	
+	@Override
+	public void update() { 
+		selectedMarks.archive();
+		if(!cancelArea.contains(lineTrace.getEndX(), lineTrace.getEndY())) {
+			canvas.getVisFrame().select(selectedMarks, rectTrace, new CommonContainerSelectFilter());
+			
+			List<Mark> toremove = new ArrayList<>();
+			for(Mark mark:selectedMarks.getMarks()) {
+				if(mark.getContainer() instanceof VisBody) {
+					toremove.add(mark);
+				}
+			}
+			selectedMarks.getMarks().removeAll(toremove);
+		}
+		
+		selectedMarks.highlight(false);
+	}
+	
+	
+	@Override
+	public void cancelComplete() {
+		super.cancelComplete();
+	}
+	
+	
+	private Mark nest(Mark mark, int targetLevel) {
+		int level = mark.getLevel();
+		if(level < targetLevel) {
+			ObservableList<Mark> sublist = FXCollections.observableArrayList();
+			sublist.add(mark);
+			return nest(new Grouping(sublist, Type.Collection).getGroup(), targetLevel);
+		} else return mark;
+	}
+	
+	
+	// TODO: Need to deal with nesting. What if I erase a parent node? 
+	public void handleRelease(MouseEvent event) {
+		super.handleRelease(event);
+
+		if(selectedMarks.isEmpty()) {
+			canvas.setActiveTool(null);
+			return;
+		}
+
+		// Take care to apply the same level of variables to all the marks that participate in the group
+		int maxLevel = 0;
+		for(Mark mark: selectedMarks.getMarks()) {
+			maxLevel = Math.max(maxLevel, mark.getLevel());
+		}
+		
+		ObservableList<Mark> marks = FXCollections.observableArrayList();
+		
+		for(Mark mark: selectedMarks.getMarks()) {
+			marks.add(nest(mark, maxLevel));
+		}
+		//////////////////////////////////////////////////////////////////////////////////////////////
+		
+		Grouping grouping = new Grouping(marks, Type.Collection);		
+	
+		canvas.getInspector().update();
+		
+		selectedMarks.archive();
+		selectedMarks.highlight(false);
+
+		canvas.setActiveTool(null);
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/CommonContainerSelectFilter.java b/src/fr/inria/structgraphics/ui/tools/CommonContainerSelectFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..46c83360f2e8ded638fc4c412829f945ca3a1867
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/CommonContainerSelectFilter.java
@@ -0,0 +1,13 @@
+package fr.inria.structgraphics.ui.tools;
+
+import java.util.ArrayList;
+
+import fr.inria.structgraphics.graphics.Mark;
+
+public class CommonContainerSelectFilter extends SelectFilter {
+
+	@Override
+	public boolean accept(ArrayList<Mark> selectedMarks, Mark mark) {
+		return selectedMarks.isEmpty() || selectedMarks.get(0).getContainer() == mark.getContainer();
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/DrawingTool.java b/src/fr/inria/structgraphics/ui/tools/DrawingTool.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed94e1e1e421023488273b519965cfa99c90ab2b
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/DrawingTool.java
@@ -0,0 +1,24 @@
+package fr.inria.structgraphics.ui.tools;
+
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import javafx.scene.Cursor;
+import javafx.scene.paint.Color;
+
+public class DrawingTool extends Tool {
+
+	protected DrawingTool() {}
+	
+	public DrawingTool(CanvasFrame canvas) {
+		super(canvas);
+	}
+	
+	@Override
+	protected void init() {
+		cursor = Cursor.CROSSHAIR;
+		traceColor = Color.DODGERBLUE;
+		traceWidth = 1;
+		
+		super.init();	
+	}
+		
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/EraserTool.java b/src/fr/inria/structgraphics/ui/tools/EraserTool.java
new file mode 100644
index 0000000000000000000000000000000000000000..2d2d22d47175c44f8240d84c07b5896a2ab8ceba
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/EraserTool.java
@@ -0,0 +1,82 @@
+package fr.inria.structgraphics.ui.tools;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.SimpleMark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.ui.inspector.DisplayUtils;
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import javafx.scene.Cursor;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+
+public class EraserTool extends Tool {
+	
+	private MarkSelection selectedMarks = new MarkSelection();
+	
+	public EraserTool(CanvasFrame canvas) {
+		super(canvas);
+				
+		traceColor = Color.RED;
+		traceWidth = 6;
+		
+		rectangular = true;
+	}
+	
+	@Override
+	protected void init() {
+		cursor = Cursor.DEFAULT;
+		tbutton =  new ToggleButton("", new ImageView(DisplayUtils.getIcon("eraser")));
+		
+		super.init();
+	}
+	
+	
+	private MarkSelection selected() {
+		return canvas.selected();
+	}
+	
+	@Override	
+	public void handlePress(MouseEvent event) {	
+		super.handlePress(event);		
+		
+		if(!selected().isEmpty()) {
+			selected().archive();
+			selected().getMarks().clear();
+			selected().highlight(true);
+		}
+	}
+	
+	public void handleDrag(MouseEvent event) { 
+		super.handleDrag(event);
+
+		selectedMarks.archive();
+		if(!cancelArea.contains(event.getX(), event.getY()))
+			canvas.getVisFrame().select(selectedMarks, rectTrace, new CommonContainerSelectFilter());
+		
+		selectedMarks.highlight(false);
+	}
+	
+	
+	// TODO: Need to deal with nesting. What if I erase a parent node? 
+	public void handleRelease(MouseEvent event) {
+		super.handleRelease(event);
+
+		for(Mark mark: selectedMarks.getMarks()) {
+			mark.setHighlight(false, true);
+			mark.fullDelete();
+		}
+		
+		canvas.getVisFrame().update();
+		canvas.getInspector().update();
+		canvas.getDataView().update();
+		
+		selectedMarks.archive();
+		//selectedMarks.highlight(false);
+
+		canvas.setActiveTool(null);
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/FlowDrawingTool.java b/src/fr/inria/structgraphics/ui/tools/FlowDrawingTool.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb1ee60594cedf00a1d0a949ca22cefa5b46789d
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/FlowDrawingTool.java
@@ -0,0 +1,111 @@
+package fr.inria.structgraphics.ui.tools;
+
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.ui.inspector.DisplayUtils;
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+
+public class FlowDrawingTool extends DrawingTool {
+	
+	private ShapeMark origin = null, destination = null;
+	
+	public FlowDrawingTool(CanvasFrame canvas) {
+		super(canvas);
+	}
+	
+	
+	@Override
+	protected void init() {
+		tbutton =  new ToggleButton("", new ImageView(DisplayUtils.getIcon("flow")));
+		super.init();
+		
+		traceColor = Color.FORESTGREEN;
+		traceWidth = 2.5;
+		
+	}
+	
+	@Override
+	public void handleMove(MouseEvent event) {	
+		ShapeMark mark = canvas.getVisFrame().getShape(event.getX(), event.getY());
+		
+		if(mark != null && mark != origin) {
+			if(origin != null) origin.showOrigin(false);
+			mark.showOrigin(true);
+			origin = mark;
+		} else if(mark == null && origin != null){
+			origin.showOrigin(false);
+			origin = null;
+		}
+	}
+	
+	@Override
+	public void handleDrag(MouseEvent event) {	
+		if(origin != null) {
+			lineTrace = createTrace(event.getX(), event.getY());
+			canvas.getCanvas().show(lineTrace, null, null);
+			
+			ShapeMark mark = canvas.getVisFrame().getShape(event.getX(), event.getY());
+			
+			boolean accept = mark != null && mark != origin  && origin.getRootVirtualGroup() == mark.getRootVirtualGroup();
+			
+			if(accept) {
+				LineConnectedCollection collection = (LineConnectedCollection)mark.getRootVirtualGroup();
+				if(collection.containtsConnection(origin, mark) || collection.hasCycle(mark, origin)) accept = false;
+				/*else if(collection.getChildPropertyStructure().areCommon(origin.height, mark.height)) {
+					accept = false;
+				}*/
+			}
+			
+			if(accept && mark != destination) {
+				if(destination != null) destination.showDestination(false);
+				mark.showDestination(true); 
+				destination = mark;
+			} else if(!accept && destination != null ) {
+				destination.showDestination(false);
+				destination = null;
+			}
+		}
+	}
+	
+	@Override
+	public void handleRelease(MouseEvent event) {
+		if(origin != null && destination != null) {
+			LineConnectedCollection collection = (LineConnectedCollection)origin.getRootVirtualGroup();
+			collection.createConnection(origin, destination, true);
+			
+			//canvas.getVisFrame().update();
+			canvas.getInspector().generateView(collection);
+			canvas.getInspector().update();
+			canvas.getInspector().setView(collection);
+			canvas.getDataView().update();
+		}
+		
+		if(destination != null) {
+			destination.showDestination(false);
+			destination = null;
+		}
+		
+		canvas.getCanvas().show(null, null, null);
+		handleMove(event);
+	}
+	
+	@Override
+	public void handlePress(MouseEvent event) {		
+		if(origin != null) {
+			super.handlePress(event);
+		}
+	}
+	
+	
+	@Override
+	public void setActive(boolean active) { 
+		super.setActive(active);
+	}
+	
+}
+
+
diff --git a/src/fr/inria/structgraphics/ui/tools/GroupCreationTool.java b/src/fr/inria/structgraphics/ui/tools/GroupCreationTool.java
new file mode 100644
index 0000000000000000000000000000000000000000..c5768a249c695032007db4da3123111f0c694018
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/GroupCreationTool.java
@@ -0,0 +1,110 @@
+package fr.inria.structgraphics.ui.tools;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.ui.inspector.DisplayUtils;
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import fr.inria.structgraphics.ui.viscanvas.groupings.Grouping;
+import fr.inria.structgraphics.ui.viscanvas.groupings.Grouping.Type;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.Cursor;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+
+public class GroupCreationTool extends Tool {
+	
+	private MarkSelection selectedMarks = new MarkSelection();
+	
+	public GroupCreationTool(CanvasFrame canvas) {
+		super(canvas);
+				
+		traceColor = Color.BLUE;
+		traceWidth = 2;
+		
+		rectangular = true;
+	}
+	
+	@Override
+	protected void init() {
+		cursor = Cursor.DEFAULT;
+		//tbutton =  new ToggleButton("", new ImageView(DisplayUtils.getIcon("construct")));
+		tbutton =  new ToggleButton("", new ImageView(DisplayUtils.getIcon("Group")));
+		
+		super.init();
+	}
+	
+	
+	@Override
+	public void update() { 
+		selectedMarks.archive();
+		if(!cancelArea.contains(lineTrace.getEndX(), lineTrace.getEndY())) {
+			canvas.getVisFrame().select(selectedMarks, rectTrace, new CommonContainerSelectFilter());
+			
+			List<Mark> toremove = new ArrayList<>();
+			for(Mark mark:selectedMarks.getMarks()) {
+				if(mark.getContainer() instanceof VisBody) {
+					toremove.add(mark);
+				}
+			}
+			selectedMarks.getMarks().removeAll(toremove);
+		}
+		
+		selectedMarks.highlight(false);
+	}
+	
+	
+	@Override
+	public void cancelComplete() {
+		super.cancelComplete();
+	}
+	
+	
+	private Mark nest(Mark mark, int targetLevel) {
+		int level = mark.getLevel();
+		if(level < targetLevel) {
+			ObservableList<Mark> sublist = FXCollections.observableArrayList();
+			sublist.add(mark);
+			return nest(new Grouping(sublist, Type.Group).getGroup(), targetLevel);
+		} else return mark;
+	}
+	
+	
+	// TODO: Need to deal with nesting. What if I erase a parent node? 
+	public void handleRelease(MouseEvent event) {
+		super.handleRelease(event);
+
+		if(selectedMarks.isEmpty()) {
+			canvas.setActiveTool(null);
+			return;
+		}
+
+		// Take care to apply the same level of variables to all the marks that participate in the group
+		int maxLevel = 0;
+		for(Mark mark: selectedMarks.getMarks()) {
+			maxLevel = Math.max(maxLevel, mark.getLevel());
+		}
+		
+		ObservableList<Mark> marks = FXCollections.observableArrayList();
+		
+		for(Mark mark: selectedMarks.getMarks()) {
+			marks.add(nest(mark, maxLevel));
+		}
+		//////////////////////////////////////////////////////////////////////////////////////////////
+		
+		Grouping grouping = new Grouping(marks, Type.Group);		
+	
+		canvas.getInspector().update();
+		
+		selectedMarks.archive();
+		selectedMarks.highlight(false);
+
+		canvas.setActiveTool(null);
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/MarkSelection.java b/src/fr/inria/structgraphics/ui/tools/MarkSelection.java
new file mode 100644
index 0000000000000000000000000000000000000000..1eb4321bcf66741e6340350065563b76b0ee538f
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/MarkSelection.java
@@ -0,0 +1,168 @@
+package fr.inria.structgraphics.ui.tools;
+
+import java.util.ArrayList;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisGroup;
+import javafx.scene.shape.Line;
+
+public class MarkSelection {
+
+	public enum SelectionType {
+		INCOLLECTION, INGROUP, UNGROUPED
+	}
+	
+	private ArrayList<Mark> marks, archived;
+	private boolean acceptDragEvent = true; // TODO: May finally do not need it!!!!
+	
+	private SelectionType type = SelectionType.UNGROUPED;
+	
+	public MarkSelection () {
+		marks = new ArrayList<>();
+	}
+	
+	public void archive() {
+		archived = marks;
+		marks = new ArrayList<>();
+	}
+	
+	public boolean isEmpty() {
+		return marks.isEmpty();
+	}
+	
+	public int size() {
+		return marks.size();
+	}
+	
+	public void removeAll() {
+		marks.clear();
+	}
+	
+	public void highlightPress() {
+		if(marks.size() != 1 || !archived.contains(marks.get(0))) {
+			highlight(true); 
+		}
+		else {
+			marks = archived;
+			for(Mark mark:marks) {
+				mark.pin();
+			}
+		}
+	}
+	
+	
+	public void highlight(boolean single) {
+		if(archived != null) {
+			for(Mark mark:archived) {
+				if(!marks.contains(mark)) {
+					mark.setHighlight(false, single);
+				}
+			}
+		}
+		
+		if(marks != null) {
+			for(Mark mark:marks) {
+				/*if(!mark.isHighlighted())*/ mark.setHighlight(true, single);
+			}
+		}
+	}
+	
+	public void add(Mark mark) {
+		Container container = mark.getContainer();
+		
+		if(container instanceof VisCollection) type = SelectionType.INCOLLECTION;
+		else if(container instanceof VisGroup) type = SelectionType.INGROUP;
+		else type = SelectionType.UNGROUPED;
+		
+		marks.add(mark);
+	}
+	
+	public SelectionType getType() {
+		return type;
+	}
+	
+	
+	private boolean isOrderConstrained() {
+		if(marks == null || marks.isEmpty()) return false;
+		Container container = marks.get(0).getContainer();
+		
+		if(container instanceof VisBody) {
+			return ((VisBody) container).isOrderConstrained();
+		} else return false;
+	}
+	
+	
+	public boolean canChangeLayers() {
+		if(marks == null || marks.isEmpty()) return false;
+		else {
+			Mark first = marks.get(0);
+			if(first instanceof LineConnectedCollection && ((LineConnectedCollection) first).isConnectionSelected()) return false;
+		}
+		
+		return !isOrderConstrained();
+	}
+	
+	public boolean canGoToLibrary() {
+		if(marks == null || marks.isEmpty() || size() > 1) return false;
+		else {
+			Mark first = marks.get(0);
+			if(first instanceof LineConnectedCollection && ((LineConnectedCollection) first).isConnectionSelected()) return false;
+		}
+		
+		return true;
+	}
+	
+	
+	public ArrayList<Mark> getMarks(){
+		return marks;
+	}
+	
+	public void translate(Line lineTrace) {
+		for(Mark mark:marks) {
+			mark.translate(lineTrace);
+		}
+	}
+	
+	public void setDragAccept(boolean accept) {
+		this.acceptDragEvent = accept;
+	}
+	
+	/*
+	public boolean acceptDragEvent() {
+		return acceptDragEvent;
+	}*/
+
+	
+	public void bringToFront() {
+		Container container = marks.get(0).getContainer();
+		
+		for(Mark mark: marks) {
+			container.bringToFront(mark);
+		}
+		
+		container.updateReordering();
+	}
+	
+	public void sendToBack() {
+		Container container = marks.get(0).getContainer();
+		
+		for(int i = marks.size() - 1; i >=0; --i) {
+			container.sendToBack(marks.get(i));
+		}
+		
+		container.updateReordering();
+	}
+
+	public void delete() {
+		for(Mark mark:marks) {
+			mark.fullDelete();
+		}
+		
+		marks.clear();
+	}	
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/MultiplyTool.java b/src/fr/inria/structgraphics/ui/tools/MultiplyTool.java
new file mode 100644
index 0000000000000000000000000000000000000000..b3e921593fdbd75118c1217540e7e3f01e75ff92
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/MultiplyTool.java
@@ -0,0 +1,214 @@
+package fr.inria.structgraphics.ui.tools;
+
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.ConnectedCollection;
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.Shadow;
+import fr.inria.structgraphics.graphics.SimpleMark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.AlignmentProperty.XSticky;
+import fr.inria.structgraphics.types.AlignmentProperty.YSticky;
+import fr.inria.structgraphics.ui.inspector.DisplayUtils;
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import fr.inria.structgraphics.ui.viscanvas.groupings.PropertyStructure;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.Cursor;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.shape.Circle;
+
+public class MultiplyTool extends Tool {
+		
+	protected Circle trace;
+	protected double traceRadius = 5;
+		
+//	private boolean pressed = false;
+	
+	private SimpleMark selected = null;
+	
+	public MultiplyTool(CanvasFrame canvas) {
+		super(canvas);
+	
+		trace = createPointTrace(-1, -1);
+		trace.setVisible(false);
+	}
+	
+	@Override
+	protected void init() {
+		cursor = Cursor.DEFAULT;
+		tbutton =  new ToggleButton("", new ImageView(DisplayUtils.getIcon("multiply")));
+		
+		super.init();
+	}
+	
+	@Override
+	public void handleMove(MouseEvent event) { 
+		trace.centerXProperty().set(event.getX());
+		trace.centerYProperty().set(event.getY());
+	}
+	
+	@Override	
+	public void handlePress(MouseEvent event) {	
+		super.handlePress(event);		
+		canvas.getCanvas().show(trace);
+
+		if(!selected().isEmpty()) {
+			selected().archive();
+			canvas.getVisFrame().monoselect(selected(), null);
+			selected().highlight(true);
+		}
+		
+		selected().archive();	
+
+		canvas.getVisFrame().monoselect(selected(), trace);
+		selected().highlight(false);
+		
+		if(!selected().isEmpty()) {
+		//	pressed = true;
+			canvas.getInspector().setView(selected().getMarks());
+			
+			Mark mark = selected().getMarks().get(0);
+			if(mark instanceof SimpleMark) {
+				selected = (SimpleMark)mark;
+				selected.setFeedForward(true);
+			}
+
+		}// else pressed = false;
+	}
+	
+	@Override
+	public void handleDrag(MouseEvent event) { 
+		super.handleDrag(event);
+		
+		if(selected != null) {
+			selected.selectCopies(lineTrace);
+		}
+	}
+	
+	
+	private MarkSelection selected() {
+		return canvas.selected();
+	}
+
+	
+	// TODO: Need to deal with nesting. What if I erase a parent node? 
+	@Override
+	public void handleRelease(MouseEvent event) { 
+		if(selected != null) { 
+			List<Shadow> copies = selected.selectCopies(lineTrace);
+			if(copies.isEmpty()) {
+				selected.setFeedForward(false);
+				selected = null;			
+				super.handleRelease(event);
+				return;
+			}
+		
+			if(selected instanceof ConnectedCollection && ((ConnectedCollection)selected).isCurveSelected() && ((ConnectedCollection)selected).isSingleSibling()) {
+				ObservableList<Mark> charts = FXCollections.observableArrayList();
+				charts.add(selected);
+				
+				for(Shadow shadow: copies) {
+					SimpleMark mark = shadow.createMark();
+					if(mark == null) continue; // TODO : ????
+					
+					mark.initProperties();
+					charts.add(mark);					
+				}
+				
+				Container container = selected.getContainer();
+				LineConnectedCollection collection = new LineConnectedCollection(container, true, charts);
+				collection.getAlignXProperty().set(YSticky.Yes);
+				collection.getAlignYProperty().set(XSticky.Yes);
+				
+				collection.getChildPropertyStructure().moveToVariable(new PropertyName(selected.strokePaint.getName()));
+				
+				// TODO
+				if(container instanceof VisBody) {
+					((VisBody)container).stickToYAxis();
+					((VisBody)container).stickToXAxis();
+				}
+				
+				for(Mark mark: collection.getComponents())
+					if(mark instanceof ConnectedCollection) ((ConnectedCollection)mark).updateInteractor();
+				
+			} else {
+				Container container = selected.getContainer();
+				Mark firstMark = null; 
+				PropertyStructure structure = null;
+				
+				if(container instanceof VisBody && container.getComponents().size() == 1) {
+					firstMark = container.getComponentAt(0);
+					structure = ((VisBody)container).getChildPropertyStructure();
+				}
+					
+				for(Shadow shadow: copies) {
+					SimpleMark mark = shadow.createMark();
+					if(mark == null) continue; // TODO : ????
+					
+					mark.initProperties();			
+					if(container instanceof VisBody) {
+						if(firstMark != null) {
+							if(mark.coords.getX() != firstMark.coords.getX() && structure.isXShared()) {
+								structure.moveToVariable(new PropertyName(firstMark.coords.x.getName()));
+							} else if(mark.coords.getY() != firstMark.coords.getY() && structure.isYShared()){
+								structure.moveToVariable(new PropertyName(firstMark.coords.y.getName()));
+							}
+						}
+						// TODO: I need something extra for marks that are groups themselves
+						((VisBody)container).addToGroup(mark);					
+					}
+					
+				}
+				if(selected.getContainer() instanceof VisBody) {
+					((VisBody)selected.getContainer()).stickToYAxis();
+					((VisBody)selected.getContainer()).stickToXAxis();
+					
+					((VisBody)selected.getContainer()).updateLayout(((VisBody)selected.getContainer()).getComponentAt(0));
+				}
+			}
+			
+			canvas.getVisFrame().update();
+			canvas.getInspector().update();
+			canvas.getDataView().update();
+			
+			selected.setFeedForward(false);
+			selected = null;
+		}
+		
+//		pressed = false;
+		
+		super.handleRelease(event);
+
+		selected().archive();		
+		canvas.getVisFrame().monoselect(selected(), null);
+		selected().highlight(false);
+		
+		canvas.setActiveTool(null);
+//		for(Mark mark: selectedMarks.getMarks()) {
+			// Linking code
+//			mark.dispose();
+//		}
+
+		/*
+		canvas.getInspector().update();
+		
+		selectedMarks.archive();
+		*/
+	}
+	
+	protected Circle createPointTrace(double x, double y) {
+		Circle trace = new Circle(x, y, traceRadius);
+		trace.setStrokeWidth(1);
+		trace.setFill(null);
+		trace.setStroke(traceColor);
+		
+		return trace;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/SelectFilter.java b/src/fr/inria/structgraphics/ui/tools/SelectFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..930e8e0f739ff53a91d366173c6108cef22dec9b
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/SelectFilter.java
@@ -0,0 +1,12 @@
+package fr.inria.structgraphics.ui.tools;
+
+import java.util.ArrayList;
+
+import fr.inria.structgraphics.graphics.Mark;
+
+public class SelectFilter {
+
+	public boolean accept(ArrayList<Mark> selectedMarks, Mark mark) {
+		return true;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/SelectTool.java b/src/fr/inria/structgraphics/ui/tools/SelectTool.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d011047792bc3fff9ec1aee8673ca15eb1433ff
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/SelectTool.java
@@ -0,0 +1,332 @@
+package fr.inria.structgraphics.ui.tools;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.SimpleMark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.persistence.JsonObjectWriter;
+import fr.inria.structgraphics.ui.inspector.DisplayUtils;
+import fr.inria.structgraphics.ui.spreadsheet.AreaInteractor;
+import fr.inria.structgraphics.ui.tools.MarkSelection.SelectionType;
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Cursor;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.SeparatorMenuItem;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Rectangle;
+import javafx.stage.WindowEvent;
+
+public class SelectTool extends Tool {
+	
+	protected Circle trace;
+	protected double traceRadius = 2;
+		
+	private boolean pressed = false;
+		
+	private ContextMenu contextMenu;
+	
+	private ArrayList<SimpleMark> clipboard = new ArrayList<>();
+	
+	public SelectTool(CanvasFrame canvas) {
+		super(canvas);
+	
+		trace = createPointTrace(-1, -1);
+		trace.setVisible(false);
+		
+		rectangular = true;
+	}
+	
+	@Override
+	protected void init() {
+		cursor = Cursor.DEFAULT;
+		tbutton = new ToggleButton("", new ImageView(DisplayUtils.getIcon("drag")));
+		
+		super.init();			
+	}
+	
+	@Override
+	public void handleMove(MouseEvent event) { 
+		super.handleMove(event);		
+		trace.centerXProperty().set(event.getX());
+		trace.centerYProperty().set(event.getY());
+	}
+	
+	public void select(Mark mark, Object source) {
+		select(mark, source, true);
+	}
+	
+	public void select(Mark mark, Object source, boolean single) {
+		selected().setDragAccept(true);		
+		selected().archive();
+		if(mark != null) selected().add(mark);
+		selected().highlight(single);
+		
+		if(!selected().isEmpty()) {
+			pressed = true;
+			if(source instanceof AreaInteractor) canvas.getInspector().setView(selected().getMarks());
+		} else pressed = false;
+	}
+	
+	public void addSelection(Mark mark, Object source) {
+		if(mark != null) selected().add(mark);
+		selected().highlight(false);
+	}
+	
+	@Override	
+	public void handlePress(MouseEvent event) {				
+		super.handlePress(event);
+				
+		canvas.getCanvas().show(trace);
+		
+		selected().setDragAccept(true);
+		selected().archive();		
+		canvas.getVisFrame().monoselect(selected(), trace);
+		
+		//selected().highlight(true);
+		selected().highlightPress();
+
+		if(!selected().isEmpty()) {
+			rectangular = false;
+			
+			pressed = true;
+			canvas.getInspector().setView(selected().getMarks());
+		} else {
+			//canvas.getInspector().setView(canvas.getVisFrame());
+			rectangular = true;
+			pressed = false;
+		}
+		
+		if(event.isSecondaryButtonDown() && !selected().isEmpty() && selected().getMarks().get(0) instanceof SimpleMark ) {
+				if(contextMenu != null) {
+					contextMenu.hide();
+					contextMenu.getItems().clear();
+				}
+				else {
+					contextMenu = new ContextMenu();
+				}
+			  					
+				addItems(contextMenu);
+		        canvas.getSplitPane().setContextMenu(contextMenu);
+		}
+	}
+	
+	
+	public void addItems(ContextMenu contextMenu) {
+		// Move Layer Position Menu Items
+		MenuItem item1 = new MenuItem("Bring to Front");
+        item1.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent event) {
+            	selected().bringToFront();
+            }
+        });
+                
+		contextMenu.getItems().add(item1);
+		//if(selected().isOrderConstrained()) item1.setDisable(true);
+		
+		MenuItem item2 = new MenuItem("Send to Back");
+        item2.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent event) {
+            	selected().sendToBack();
+            }
+        });
+		contextMenu.getItems().add(item2);
+		//if(selected().isOrderConstrained()) item2.setDisable(true);
+		
+		
+		contextMenu.getItems().add(new SeparatorMenuItem());
+		
+		// Remove marks!
+		MenuItem item3 = new MenuItem("Delete");
+        item3.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent event) {
+            	selected().delete();
+                  	
+        		canvas.getInspector().update();
+        		canvas.getDataView().update();
+            }
+        });
+		contextMenu.getItems().add(item3);
+			
+        MenuItem item4 = new MenuItem("Add to Library");
+        item4.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent event) {
+            	canvas.getLibrary().addToLibrary((SimpleMark)selected().getMarks().get(0));
+            }
+        });
+        contextMenu.getItems().add(item4);
+        
+        
+        MenuItem item5 = new MenuItem("Save As");
+        item5.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent event) {
+            	canvas.saveAs(canvas.getStage(),
+            			JsonObjectWriter.saveToJason(selected().getMarks(), false));
+            }
+        });
+        contextMenu.getItems().add(item5);
+        
+		
+		contextMenu.setOnShowing(new EventHandler<WindowEvent>() {
+			@Override
+			public void handle(WindowEvent event) {
+				boolean activeLayers = selected().canChangeLayers();
+				
+				item1.setDisable(!activeLayers);
+				item2.setDisable(!activeLayers);
+				item4.setDisable(!selected().canGoToLibrary());
+			}
+			
+		});
+		
+        contextMenu.setOnHiding(new EventHandler<WindowEvent>() {
+			@Override
+			public void handle(WindowEvent event) {
+				canvas.getSplitPane().setContextMenu(null);
+			}
+		});
+	}
+	
+	@Override
+	public void update() {
+		if(!pressed) {
+			selected().archive();
+			if(!cancelArea.contains(lineTrace.getEndX(), lineTrace.getEndY()))
+				canvas.getVisFrame().select(selected(), /*lineTrace*/ rectTrace, new CommonContainerSelectFilter());
+			
+			selected().highlight(false);
+			
+			//if(selected().getMarks().size() > 1) selected().highlight(false);
+			//else selected().highlight(true);
+		} else {			
+			//if(selected().acceptDragEvent()) 
+			selected().translate(lineTrace);
+			//canvas.getInspector().update();
+		}
+	}
+	
+	private MarkSelection selected() {
+		return canvas.selected();
+	}
+	
+	public Collection<Mark> getSelected(){
+		return canvas.selected().getMarks();
+	}
+	
+	// TODO: Need to deal with nesting. What if I erase a parent node? 
+	@Override
+	public void handleRelease(MouseEvent event) {
+		if(!pressed){
+			if(selected().getMarks().size() > 1) {
+				selected().highlight(false);
+			}
+			else selected().highlight(true);
+			
+			canvas.getInspector().setView(selected().getMarks());
+		}
+		
+		pressed = false;
+		
+		super.handleRelease(event);
+
+		for(Mark mark: selected().getMarks()) { 
+			mark.mouseRelease();
+			// Update the coordinates of the marks in the virtual group enclosing the released mark!!!
+			if(mark.getContainer() instanceof VisBody) {
+				//((VirtualGroup)mark.getContainer()).lockProperties();
+				//((VirtualGroup)mark.getContainer()).refresh();
+				//((VirtualGroup)mark.getContainer()).unlockProperties();
+			}
+			// Linking code
+//			mark.dispose();
+		}
+	}
+
+	
+	@Override
+	public void setActive(boolean active) { 
+		super.setActive(active);
+		if(active) {
+			selected().highlight(true);
+		} else {
+			selected().archive();
+			selected().highlight(true);
+		}
+	}
+	
+	@Override
+	public void cancelComplete() {
+		super.cancelComplete();
+		pressed = false;
+	}
+	
+	
+	protected Rectangle createRectSelection(double x, double y, double width, double height) {
+		Rectangle rectTrace = new Rectangle(x, y, width, height);
+		rectTrace.setStrokeWidth(rectWidth);
+		rectTrace.getStrokeDashArray().addAll(3.0,7.0,3.0,7.0);
+		rectTrace.setStroke(rectColor);
+		rectTrace.setFill(rectFill);
+		
+		return rectTrace;
+	}
+	
+	
+	protected Circle createPointTrace(double x, double y) {
+		Circle trace = new Circle(x, y, traceRadius);
+		trace.setStrokeWidth(1);
+		trace.setFill(null);
+		trace.setStroke(traceColor);
+		
+		return trace;
+	}
+	
+	
+	protected void copyAction() {
+		if(selected().isEmpty()) return;
+		else {
+			clipboard.clear();
+		}
+		
+		for(Mark mark: selected().getMarks()) { 
+			if(mark instanceof SimpleMark) clipboard.add((SimpleMark)mark);
+		}
+	}
+	
+	protected void pasteAction(double x, double y) {
+		if(clipboard.isEmpty()) return;
+
+		double meanX = 0, meanY = 0;
+		for(Mark mark: clipboard) { 			
+			meanX += mark.getGlobalX();
+			meanY += mark.getGlobalY();
+		}
+		
+		meanX = meanX / clipboard.size();
+		meanY = meanY / clipboard.size();
+		
+		for(SimpleMark mark: clipboard) { 
+			SimpleMark copy = mark.createCopy(canvas.getVisFrame(), 0, 0);
+			copy.initProperties(); 
+			copy.getCoords().x.set(x + mark.getGlobalX() - meanX);
+			copy.getCoords().y.set((canvas.getVisFrame().height.get() - y) + mark.getGlobalY() - meanY);
+			copy.update();
+		}
+		
+		canvas.getInspector().update();
+		
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/tools/ShapeDrawingTool.java b/src/fr/inria/structgraphics/ui/tools/ShapeDrawingTool.java
new file mode 100644
index 0000000000000000000000000000000000000000..26775040d8539f8b15e12d51ff58f945826847ed
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/ShapeDrawingTool.java
@@ -0,0 +1,134 @@
+package fr.inria.structgraphics.ui.tools;
+
+import fr.inria.structgraphics.graphics.PositionCoords;
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.graphics.TextualMark;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.types.ShapeProperty.Type;
+import fr.inria.structgraphics.ui.inspector.DisplayUtils;
+import fr.inria.structgraphics.ui.utils.CoordTransformer;
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import javafx.scene.Cursor;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+
+public class ShapeDrawingTool extends DrawingTool {
+
+	protected ShapeMark tempMark;
+	private ShapeProperty.Type type;
+	
+	public ShapeDrawingTool(CanvasFrame canvas, ShapeProperty.Type type) {
+		this.canvas = canvas;
+		this.type = type;
+		init();
+	}
+	
+	@Override
+	protected void init() {
+		cursor = Cursor.CROSSHAIR;
+		tbutton =  new ToggleButton("", new ImageView(DisplayUtils.getIcon(type.toString())));
+		super.init();
+	}
+	
+	public void update() {
+		if(tempMark == null) {
+			if(!cancelArea.contains(lineTrace.getEndX(), lineTrace.getEndY())) {
+				tempMark = createMark();
+				canvas.getInspector().update();
+				canvas.getInspector().setView(tempMark);
+			}
+		} else {
+			if(!cancelArea.contains(lineTrace.getEndX(), lineTrace.getEndX())) updateMark();
+			else { 
+				tempMark.dispose(); // TODO: ????
+				
+				canvas.getInspector().update();
+				tempMark = null;
+			}
+		}
+	}
+	
+	@Override
+	public void cancelComplete() {
+		super.cancelComplete();
+		tempMark.dispose();
+		canvas.getInspector().update();
+		tempMark = null;
+	}
+
+	
+	public void handleRelease(MouseEvent event) {
+		super.handleRelease(event);
+		
+	//	tempMark.setHighlight(true, true);
+		tempMark = null;
+		
+	//	canvas.setActiveTool(null);
+		
+		// TODO
+	}
+
+
+	protected ShapeMark createMark() {
+		VisFrame visFrame = canvas.getVisFrame(); // This will eventually become more sophisticated! 
+		
+		RefX refX = RefX.Center;
+		RefY refY = RefY.Bottom;	
+	
+		double w = (type == Type.Line) ? lineTrace.getEndX() - lineTrace.getStartX() : Math.abs((lineTrace.getEndX() - lineTrace.getStartX()));
+		double h = (type == Type.Line) ? lineTrace.getEndY() - lineTrace.getStartY() : Math.abs((lineTrace.getEndY() - lineTrace.getStartY()));
+		
+		double x = (type == Type.Line) ?
+				CoordTransformer.getXPosition(visFrame.getRefCoords(), refX, visFrame.width.get(), lineTrace.getStartX(), w) : 
+				CoordTransformer.getXPosition(visFrame.getRefCoords(), refX, visFrame.width.get(), Math.min(lineTrace.getStartX(), lineTrace.getEndX()), w);
+		
+		double y = (type == Type.Line) ?
+				CoordTransformer.getYPosition(visFrame.getRefCoords(), refY, visFrame.height.get(), -lineTrace.getStartY(), h) : 
+				CoordTransformer.getYPosition(visFrame.getRefCoords(), refY, visFrame.height.get(), -Math.min(lineTrace.getStartY(), lineTrace.getEndY()), h);
+		
+		
+		ShapeMark mark = ShapeMark.createInstance(visFrame, true, type, w, h);
+		
+		PositionCoords coords = new PositionCoords(mark, x, y);
+		mark.setCoords(coords);
+		
+		// TODO
+		mark.setDefaults();
+		
+		mark.initProperties();
+		mark.updateShape();
+		
+		return mark;
+	}
+	
+	
+	protected void updateMark() { 
+		if(tempMark!= null) {
+					
+			VisFrame visFrame = (VisFrame)tempMark.getContainer();
+			
+			double w = (type == Type.Line) ? lineTrace.getEndX() - lineTrace.getStartX() : Math.abs((lineTrace.getEndX() - lineTrace.getStartX()));
+			double h = (type == Type.Line) ? lineTrace.getEndY() - lineTrace.getStartY() :  Math.abs((lineTrace.getEndY() - lineTrace.getStartY()));
+			
+			double x = (type == Type.Line) ?
+					CoordTransformer.getXPosition(visFrame.getRefCoords(), tempMark.getCoords().getXRef(), visFrame.width.get(), lineTrace.getStartX(), w) : 
+					CoordTransformer.getXPosition(visFrame.getRefCoords(), tempMark.getCoords().getXRef(), visFrame.width.get(), Math.min(lineTrace.getStartX(), lineTrace.getEndX()), w);
+			
+			double y = (type == Type.Line) ?
+					CoordTransformer.getYPosition(visFrame.getRefCoords(), tempMark.getCoords().getYRef(), visFrame.height.get(), -lineTrace.getStartY(), h) :
+					CoordTransformer.getYPosition(visFrame.getRefCoords(), tempMark.getCoords().getYRef(), visFrame.height.get(), -Math.min(lineTrace.getStartY(), lineTrace.getEndY()), h);
+			
+			tempMark.setPositionCoords(x, y);
+			
+			tempMark.width.set(w);
+			tempMark.height.set(h);
+		}
+	}
+	
+}
+
diff --git a/src/fr/inria/structgraphics/ui/tools/Tool.java b/src/fr/inria/structgraphics/ui/tools/Tool.java
new file mode 100644
index 0000000000000000000000000000000000000000..d104cad524422fbea3c6e0150a37028fb4fe31c5
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/tools/Tool.java
@@ -0,0 +1,176 @@
+package fr.inria.structgraphics.ui.tools;
+
+import fr.inria.structgraphics.ui.viscanvas.CanvasFrame;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Cursor;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.shape.Shape;
+import javafx.util.Duration;
+
+public class Tool {
+	
+	private final static int CANCEL_RADIUS = 0;
+	
+	protected double startX, startY, mouseX, mouseY;
+	protected Line lineTrace;
+	protected Rectangle rectTrace;
+	protected Shape cancelArea;
+		
+	protected ToggleButton tbutton = null;
+	protected boolean isActive = false;
+	protected Cursor cursor = Cursor.DEFAULT;
+	protected CanvasFrame canvas;
+	
+	protected double traceWidth = 3;
+	protected Paint traceColor = Color.CORAL;
+	
+	protected double rectWidth = 1;
+	protected Paint rectColor = Color.DARKGRAY;
+	protected Paint rectFill = new Color(1, 1, 1, .1);
+	
+	protected boolean canceled = false;
+	protected boolean rectangular = false;
+
+	protected Tool() {}
+	
+	public Tool(CanvasFrame canvas) {
+		this.canvas = canvas;
+		init();
+	}
+	
+	protected void init() {
+		if(tbutton != null) tbutton.setOnAction(
+				new EventHandler<ActionEvent>() {
+					@Override 
+					public void handle(ActionEvent e) {
+						if(!isActive) setActive(true);
+						else tbutton.setSelected(true);
+					}
+				});
+	}
+	
+	public boolean hasToggleButton() {
+		return true;
+	}
+	
+	protected void cancelAction() {
+		canceled = true;
+		CancelTranslateTransition transition = new CancelTranslateTransition(Duration.millis(160), this);
+		transition.play();
+	}
+	
+	protected void copyAction() {}
+	protected void pasteAction(double x, double y) {}
+	
+	public void cancelComplete() {
+		canvas.getCanvas().show(null, null, null);
+	}
+	
+	public ToggleButton getToggleButton() {
+		return tbutton;
+	}
+	
+	public void setActive(boolean active) { 
+		this.isActive = active;
+		if(active) {
+			if(tbutton != null) tbutton.setSelected(true);
+			canvas.setActiveTool(this);
+			if(cursor!= null) canvas.setCanvasCursor(cursor);
+			
+			canvas.setOnKeyPressed(new EventHandler<KeyEvent>() {
+				@Override
+				public void handle(KeyEvent event) {
+					if(event.getCode() == KeyCode.ESCAPE)
+						cancelAction();
+					else if(event.isMetaDown() && event.getCode() == KeyCode.C)
+						copyAction();
+					else if(event.isMetaDown() && event.getCode() == KeyCode.V)
+						pasteAction(mouseX, mouseY);
+				}
+			});
+			
+		} else if(tbutton != null) tbutton.setSelected(false);
+	}
+	
+	public boolean getActive() {
+		return isActive;
+	}
+
+	public void handleDrag(MouseEvent event) { 
+		if(canceled) return;
+		
+		lineTrace = createTrace(event.getX(), event.getY());
+		cancelArea = createCancelArea(event.getX(), event.getY());
+		if(rectangular) {
+			rectTrace = createRectTrace(event.getX(), event.getY());
+		} else rectTrace = null;
+			
+		canvas.getCanvas().show(lineTrace, cancelArea, rectTrace);
+		update();
+	}
+	
+	public void update() {
+		
+	}
+	
+	public void handleMove(MouseEvent event) {
+		mouseX = event.getX();
+		mouseY = event.getY();
+	}
+
+	public void handlePress(MouseEvent event) {
+		canceled = false;
+		
+		startX = event.getX();
+		startY = event.getY();	
+		lineTrace = createTrace(event.getX(), event.getY());
+
+		cancelArea = createCancelArea(event.getX(), event.getY());
+		canvas.getCanvas().show(null, cancelArea, null);
+	}
+	
+	public void handleRelease(MouseEvent event) {
+		canvas.getCanvas().show(null, null, null);
+	}
+	
+	// This is a default implementation if the canel area, but it could be overriden
+	protected Shape createCancelArea(double x, double y) {
+		Shape cancelArea = new Circle(startX, startY, CANCEL_RADIUS);
+		cancelArea.setStrokeWidth(1);
+		cancelArea.setStroke(Color.RED);
+		cancelArea.setFill(Color.TRANSPARENT);
+		
+		return cancelArea;
+	}
+	
+	protected Line createTrace(double x, double y) {
+		Line lineTrace = new Line(startX, startY, x, y);
+		lineTrace.setStrokeWidth(traceWidth);
+		lineTrace.setStroke(traceColor);
+		
+		return lineTrace;
+	}
+	
+	protected Rectangle createRectTrace(double x, double y) {
+		Rectangle rectTrace = new Rectangle(Math.min(startX, x), Math.min(startY, y), Math.abs(x - startX), Math.abs(y - startY));
+		rectTrace.setStrokeWidth(rectWidth);
+		rectTrace.getStrokeDashArray().addAll(3.0,7.0,3.0,7.0);
+		rectTrace.setStroke(rectColor);
+		rectTrace.setFill(rectFill);
+		
+		return rectTrace;
+	}
+
+	public void doubleClicked(MouseEvent event) {}
+
+}
+
diff --git a/src/fr/inria/structgraphics/ui/utils/BidirectionalBindings.java b/src/fr/inria/structgraphics/ui/utils/BidirectionalBindings.java
new file mode 100644
index 0000000000000000000000000000000000000000..520f448d41529285d0be44ab1b0a2a8eb185528b
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/utils/BidirectionalBindings.java
@@ -0,0 +1,46 @@
+package fr.inria.structgraphics.ui.utils;
+
+import javafx.beans.property.Property;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.util.Pair;
+
+// See: http://carl-witt.de/customized-bidirectional-bindings-in-javafx/
+
+public class BidirectionalBindings {
+	   /** Executes updateB when propertyA is changed. Executes updateA when propertyB is changed.
+     * Makes sure that no update loops are caused by mutual updates.
+	 * @return 
+     */
+    public static <A,B> Pair<ChangeListener<A>, ChangeListener<B>> bindBidirectional(Property<A> propertyA, Property<B> propertyB,
+    		ChangeListener<A> updateB, ChangeListener<B> updateA){
+        ChangeListener<A> listenerA = addFlaggedChangeListener(propertyA, updateB);
+        ChangeListener<B> listenerB = addFlaggedChangeListener(propertyB, updateA);
+        
+        return new Pair<ChangeListener<A>, ChangeListener<B>>(listenerA, listenerB);
+    }
+    
+    public static <A,B>  void unbindBidirectional(Property<A> property1, Property<B> property2, Pair<ChangeListener<A>, ChangeListener<B>> pair) {
+    	property1.removeListener(pair.getKey());
+    	property2.removeListener(pair.getValue());
+    }
+
+    private static <T> ChangeListener<T> addFlaggedChangeListener(Property<T> property, ChangeListener<T> updateProperty){
+    	ChangeListener<T> listener = new ChangeListener<T>() {
+	        private boolean alreadyCalled = false;
+	        
+	        @Override public void changed(ObservableValue<? extends T> observable, T oldValue, T newValue) {
+	            if(alreadyCalled) return;
+	            try {
+	                alreadyCalled = true;
+	                updateProperty.changed(observable,oldValue,newValue);
+	            }
+	            finally { alreadyCalled = false; }
+	        }
+        };
+    	
+        property.addListener(listener);
+        
+        return listener;
+    }
+}
diff --git a/src/fr/inria/structgraphics/ui/utils/Cloner.java b/src/fr/inria/structgraphics/ui/utils/Cloner.java
new file mode 100644
index 0000000000000000000000000000000000000000..299e53cd1c314deb87ad56f92164aed4bd3922a0
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/utils/Cloner.java
@@ -0,0 +1,92 @@
+package fr.inria.structgraphics.ui.utils;
+
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.CubicCurveTo;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.PathElement;
+import javafx.scene.shape.QuadCurveTo;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.shape.Shape;
+
+public class Cloner {
+	
+	public static Shape clone(Shape shape) {
+		
+		if(shape instanceof Rectangle){
+			Rectangle clone = new Rectangle(((Rectangle) shape).getX(), ((Rectangle) shape).getY(), ((Rectangle) shape).getWidth(), ((Rectangle) shape).getHeight());
+			
+			/*
+			clone.xProperty().bind(((Rectangle) shape).xProperty());
+			clone.yProperty().bind(((Rectangle) shape).yProperty());
+			clone.widthProperty().bind(((Rectangle) shape).widthProperty());
+			clone.heightProperty().bind(((Rectangle) shape).heightProperty());
+			*/
+			
+			return clone;
+		} else if(shape instanceof Circle){
+			Circle clone = new Circle(((Circle) shape).getCenterX(), ((Circle) shape).getCenterY(), ((Circle) shape).getRadius());
+			
+			/*
+			clone.centerXProperty().bind(((Circle) shape).centerXProperty());
+			clone.centerYProperty().bind(((Circle) shape).centerYProperty());
+			clone.radiusProperty().bind(((Circle) shape).radiusProperty());
+			*/
+			
+			return clone;
+		} else if(shape instanceof Line){
+			Line clone = new Line(((Line) shape).getStartX(), ((Line) shape).getStartY(), ((Line) shape).getEndX(), ((Line) shape).getEndY());
+			
+			/*
+			clone.startXProperty().bind(((Line) shape).startXProperty());
+			clone.startYProperty().bind(((Line) shape).startYProperty());
+			clone.endXProperty().bind(((Line) shape).endXProperty());
+			clone.endYProperty().bind(((Line) shape).endYProperty());
+			*/
+			
+			return clone;
+		}  else if(shape instanceof Path){
+			Path clone = new Path(((Path) shape).getElements());
+				
+			/*
+			Path clone = new Path();
+			for(PathElement e: ((Path) shape).getElements()) {
+				if(e instanceof MoveTo) {
+					MoveTo mt = new MoveTo();
+					mt.xProperty().bind(((MoveTo)e).xProperty());
+					mt.yProperty().bind(((MoveTo)e).yProperty());
+					clone.getElements().add(mt);
+				} else if(e instanceof LineTo) {
+					LineTo lt = new LineTo();
+					lt.xProperty().bind(((LineTo)e).xProperty());
+					lt.yProperty().bind(((LineTo)e).yProperty());
+					clone.getElements().add(lt);					
+				} else if(e instanceof QuadCurveTo) {
+					QuadCurveTo qt = new QuadCurveTo();
+					qt.xProperty().bind(((QuadCurveTo)e).xProperty());
+					qt.yProperty().bind(((QuadCurveTo)e).yProperty());				
+					qt.controlXProperty().bind(((QuadCurveTo)e).controlXProperty());
+					qt.controlYProperty().bind(((QuadCurveTo)e).controlYProperty());
+					clone.getElements().add(qt);					
+				} else if(e instanceof CubicCurveTo) {
+					CubicCurveTo ct = new CubicCurveTo();
+					ct.xProperty().bind(((CubicCurveTo)e).xProperty());
+					ct.yProperty().bind(((CubicCurveTo)e).yProperty());				
+					ct.controlX1Property().bind(((CubicCurveTo)e).controlX1Property());
+					ct.controlY1Property().bind(((CubicCurveTo)e).controlY1Property());
+					ct.controlX2Property().bind(((CubicCurveTo)e).controlX2Property());
+					ct.controlY2Property().bind(((CubicCurveTo)e).controlY2Property());
+					clone.getElements().add(ct);					
+				}
+			}*/
+			
+			return clone;
+		} 		
+		
+		// TODO: ...
+		return null;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/utils/CoordTransformer.java b/src/fr/inria/structgraphics/ui/utils/CoordTransformer.java
new file mode 100644
index 0000000000000000000000000000000000000000..ead5643d5f536fa8fa29e3dbb795a6c4e769dad0
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/utils/CoordTransformer.java
@@ -0,0 +1,42 @@
+package fr.inria.structgraphics.ui.utils;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+
+public class CoordTransformer {
+
+	public static double getXPosition(ReferenceCoords refCoords, RefX ref, double containerWidth, double x, double w) {		
+		RefX containerRef = refCoords.containerXRef.get();
+		double offset = 0;
+		if(containerRef == RefX.Center) offset = containerWidth / 2;
+		else if(containerRef == RefX.Right) offset =  containerWidth;
+		
+		if(ref == RefX.Left) {
+			return x - offset;
+		}
+		else if(ref == RefX.Center) {
+			return x + w/2 - offset;
+		}
+		else {
+			return x + w - offset;
+		}
+	}
+	
+	public static double getYPosition(ReferenceCoords refCoords, RefY ref, double containerHeight, double y, double h) {		
+		RefY containerRef = refCoords.containerYRef.get();
+		double offset = 0;
+		if(containerRef == RefY.Center) offset = containerHeight / 2;
+		else if(containerRef == RefY.Bottom) offset =  containerHeight;
+		
+		if(ref == RefY.Top) {
+			return y + offset;
+		}
+		else if(ref == RefY.Center) {
+			return y - h/2 + offset;
+		}
+		else {
+			return y - h + offset;
+		}
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/utils/FlowConnectionBinding.java b/src/fr/inria/structgraphics/ui/utils/FlowConnectionBinding.java
new file mode 100644
index 0000000000000000000000000000000000000000..947c7eb62f491d7ac69b3b97bdb62ee68a2341bc
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/utils/FlowConnectionBinding.java
@@ -0,0 +1,318 @@
+package fr.inria.structgraphics.ui.utils;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.ui.viscanvas.groupings.FlowConnection;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
+/*
+ * This binding mechanism ensures that updates of flow marks heights and flow sizes are correctly propagates without loops
+ */
+
+public class FlowConnectionBinding {
+	
+	private ShapeMark mark;
+	private ArrayList<FlowConnection> inwardConnections, outwardConnections;
+	
+	// Original Listeners
+	private LockedChangeListener backwardsListener, forwardsListener;
+	private Hashtable<FlowConnection, LockedChangeListener> fromBackListeners, fromFrontListeners;
+	
+	private boolean lock = false;
+	
+	public FlowConnectionBinding(ShapeMark mark) {
+		this.mark = mark;
+		inwardConnections = new ArrayList<FlowConnection>();
+		outwardConnections = new ArrayList<FlowConnection>();
+		
+		fromBackListeners = new Hashtable<>();
+		fromFrontListeners = new Hashtable<>();
+		
+		backwardsListener = new LockedChangeListener() {			
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+	            if(alreadyCalled || lock) return;
+	            try {
+	            	for(LockedChangeListener listener: fromBackListeners.values()) {
+	            		listener.alreadyCalled = true;
+	            	}
+	            
+	            	updateInwardConnections(oldValue.doubleValue(), newValue.doubleValue());
+	            	
+	            }
+	            finally { 
+	            	for(LockedChangeListener listener: fromBackListeners.values()) {
+	            		listener.alreadyCalled = false;
+	            	}
+	            }
+			}
+		};
+		
+		forwardsListener = new LockedChangeListener() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+	            if(alreadyCalled || lock) return;
+	            try {
+	            	for(LockedChangeListener listener: fromFrontListeners.values()) {
+	            		listener.alreadyCalled = true;
+	            	}
+	            
+	            	updateOutwardConnections(oldValue.doubleValue(), newValue.doubleValue());
+	            	
+	            }
+	            finally { 
+	            	for(LockedChangeListener listener: fromFrontListeners.values()) {
+	            		listener.alreadyCalled = false;
+	            	}
+	            }
+			}
+		};
+		
+		mark.height.addListener(backwardsListener);
+		mark.height.addListener(forwardsListener);
+	}
+	
+	public ArrayList<FlowConnection> getInwardConnections(){
+		return inwardConnections;
+	}
+	
+	public ArrayList<FlowConnection> getOutwardConnections(){
+		return outwardConnections;
+	}
+	
+	private void updateOutwardConnections(double oldvalue, double newvalue) {		
+		if(outwardConnections.isEmpty() || newvalue > oldvalue) return;
+		
+		double sum = 0;
+		for(FlowConnection conn:outwardConnections) {
+			sum += conn.weight.get();
+		}
+		
+		if(sum <= mark.height.get()) return;
+		
+		double sum_ = 0;
+		for(int i = 0; i < outwardConnections.size() - 1; ++i) {
+			FlowConnection conn = outwardConnections.get(i);
+			double ratio = conn.weight.doubleValue()/sum;
+			double w = abs(ratio*newvalue);
+			conn.weight.set(w);
+			sum_ += w;
+		}
+		
+		FlowConnection conn = outwardConnections.get(outwardConnections.size() - 1);
+		conn.weight.set(abs(newvalue - sum_));
+	}
+	
+	private void updateInwardConnections(double oldvalue, double newvalue) {
+		if(inwardConnections.isEmpty() || newvalue > oldvalue) return;
+		
+		double sum = 0;
+		for(FlowConnection conn:inwardConnections) {
+			sum += conn.weight.get();
+		}
+		
+		if(sum <= mark.height.get()) return;
+		
+		// TODO: Find a more precise calculation method...
+		double ratio = newvalue / oldvalue;
+
+		sum = 0;
+		for(int i = 0; i < inwardConnections.size() - 1; ++i) {
+			FlowConnection conn = inwardConnections.get(i);
+			double w = abs(ratio*conn.weight.doubleValue());
+			conn.weight.set(w);
+			sum += w;
+		}
+		
+		FlowConnection conn = inwardConnections.get(inwardConnections.size() - 1);
+		conn.weight.set(abs(newvalue - sum));
+	}
+	
+	
+	private void updateOutwardConnections2(double oldvalue, double newvalue) {		
+		if(outwardConnections.isEmpty()) return;
+		
+		double sum = 0;
+		for(FlowConnection conn:outwardConnections) {
+			sum += conn.weight.get();
+		}
+
+// TODO: To uncomment to allow for inpomplete outbound flows
+//		if(newvalue > sum) return;
+		
+		double sum_ = 0;
+		for(int i = 0; i < outwardConnections.size() - 1; ++i) {
+			FlowConnection conn = outwardConnections.get(i);
+			double ratio = conn.weight.doubleValue()/sum;
+			double w = abs(ratio*newvalue);
+			conn.weight.set(w);
+			sum_ += w;
+		}
+		
+		FlowConnection conn = outwardConnections.get(outwardConnections.size() - 1);
+		conn.weight.set(abs(newvalue - sum_));
+	}
+	
+	private void updateInwardConnections2(double oldvalue, double newvalue) {
+		if(inwardConnections.isEmpty()) return;
+		
+		// TODO: Find a more precise calculation method...
+		double ratio = newvalue / oldvalue;
+
+		double sum = 0;
+		for(int i = 0; i < inwardConnections.size() - 1; ++i) {
+			FlowConnection conn = inwardConnections.get(i);
+			double w = abs(ratio*conn.weight.doubleValue());
+			conn.weight.set(w);
+			sum += w;
+		}
+		
+		FlowConnection conn = inwardConnections.get(inwardConnections.size() - 1);
+		conn.weight.set(abs(newvalue - sum));
+	}
+	
+		
+	private void updateFromFront2(FlowConnection destination, double oldvalue, double newvalue) {
+		double w = 0;
+		for(FlowConnection connection: outwardConnections) {
+			w += connection.weight.get();
+		}
+		
+		// TODO: To uncomment to allow for inpomplete outbound flows
+		//if(mark.height() < w) 
+			mark.height.set(w);
+	}
+	
+	private void updateFromBack2(FlowConnection origin, double oldvalue, double newvalue) {
+		double w = 0;
+		for(FlowConnection connection: inwardConnections) {
+			w += connection.weight.get();
+		}
+		
+		mark.height.set(w);
+			
+		//mark.height.set(mark.height() - oldvalue + newvalue);
+	}
+
+	
+	private void updateFromFront(FlowConnection destination, double oldvalue, double newvalue) {
+		updateHeight();
+	}
+	
+	private void updateFromBack(FlowConnection origin, double oldvalue, double newvalue) {
+		updateHeight();
+	}
+	
+	private void updateHeight() {
+		double w1 = 0;
+		for(FlowConnection connection: outwardConnections) {
+			w1 += connection.weight.get();
+		}
+		
+		double w2 = 0;
+		for(FlowConnection connection: inwardConnections) {
+			w2 += connection.weight.get();
+		}
+		
+		mark.height.set(Math.max(w1, w2));
+	}
+	
+	private double abs(double w) {
+		return Math.abs(w);
+	}
+	
+	public void addInwardConnection(FlowConnection connection) {
+		inwardConnections.add(connection);
+		
+		LockedChangeListener listener = new LockedChangeListener() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+	            if(alreadyCalled || lock) return;
+	            try {
+	            	backwardsListener.alreadyCalled = true;
+	            	updateFromBack(connection, oldValue.doubleValue(), newValue.doubleValue());
+	            }
+	            finally { 
+	            	backwardsListener.alreadyCalled = false;
+	            }
+			}
+		};
+		
+		fromBackListeners.put(connection, listener);
+		connection.weight.addListener(listener);
+	}
+	
+	public void addOutwardConnection(FlowConnection connection) {
+		outwardConnections.add(connection);
+		
+		LockedChangeListener listener = new LockedChangeListener(){
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+	            if(alreadyCalled || lock) return;
+	            try {
+	            	forwardsListener.alreadyCalled = true;
+	            	updateFromFront(connection, oldValue.doubleValue(), newValue.doubleValue());
+	            }
+	            finally { 
+	            	forwardsListener.alreadyCalled = false;
+	            }
+			}
+		};
+		
+		fromFrontListeners.put(connection, listener);
+		connection.weight.addListener(listener);
+	}
+	
+	public void removeInwardConnection(FlowConnection connection) {
+		inwardConnections.remove(connection);
+		
+		LockedChangeListener listener = fromFrontListeners.get(connection);
+		if(listener != null) connection.weight.removeListener(listener);
+		fromFrontListeners.remove(connection);
+	}
+	
+	public void removeOutwardConnection(FlowConnection connection) {
+		outwardConnections.remove(connection);
+		
+		LockedChangeListener listener = fromBackListeners.get(connection);
+		if(listener != null) connection.weight.removeListener(listener);
+		fromBackListeners.remove(connection);
+	}
+	
+	
+	public void destroy() {
+    	for(FlowConnection connection: fromFrontListeners.keySet()) {
+    		connection.weight.removeListener(fromFrontListeners.get(connection));
+    		connection.destroy();
+    		connection.detachFront();
+    	}
+		
+    	for(FlowConnection connection: fromBackListeners.keySet()) {
+    		connection.weight.removeListener(fromBackListeners.get(connection));
+    		connection.destroy();
+    		connection.detachBack();
+    	}
+
+		mark.height.removeListener(backwardsListener);
+		mark.height.removeListener(forwardsListener);
+    	
+    	fromFrontListeners.clear();
+    	fromBackListeners.clear();
+    	inwardConnections.clear(); 
+    	outwardConnections.clear();    	
+	}
+	
+	class LockedChangeListener implements ChangeListener<Number> {
+		protected boolean alreadyCalled = false;
+
+		@Override
+		public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {}
+	}
+
+	public void lockListeners(boolean lock) {
+		this.lock = lock;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/utils/GroupBinding.java b/src/fr/inria/structgraphics/ui/utils/GroupBinding.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ee68edffe7c923b0e7892547fd4af232daf76bc
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/utils/GroupBinding.java
@@ -0,0 +1,179 @@
+package fr.inria.structgraphics.ui.utils;
+
+import java.util.ArrayList;
+
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.Shareable;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.Property;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
+// See: http://carl-witt.de/customized-bidirectional-bindings-in-javafx/
+
+public class GroupBinding<A> {
+	
+	private ArrayList<ChangeListener<A>> originListeners = null;
+	private ArrayList<LockedChangeListener> listeners = new ArrayList<>();
+	private ArrayList<Property<A>> properties;
+		
+	private GroupBinding<Boolean> visibilityBindings = null;
+	
+	
+	public GroupBinding(ArrayList<Property<A>> properties, boolean withVisibility) {
+		this.properties = properties;
+		
+		if(withVisibility) {
+			visibilityBindings = createVisibilityBindings();
+			rebind();
+		}			
+	}
+	
+	public GroupBinding(ArrayList<Property<A>> properties) {
+		this(properties, true);
+	}
+	
+	public GroupBinding(ArrayList<Property<A>> properties, ArrayList<ChangeListener<A>> listeners) {		
+		this.properties = properties;
+		this.originListeners = listeners;
+		visibilityBindings = createVisibilityBindings();
+		
+		rebind();
+	}
+	
+	private GroupBinding<Boolean> createVisibilityBindings() {
+		ArrayList<BooleanProperty> visProperties = new ArrayList<>();
+		for(Property prop: properties)
+			visProperties.add(((Shareable)prop).getPublicProperty());
+		
+		return new GroupBinding(visProperties, false);
+	}
+	
+	public boolean hasValue(Property<A> property) {
+		return (!properties.isEmpty() && properties.get(0).getValue().equals(property.getValue()));
+	}
+	
+	public boolean contains(Property<A> property) {
+		return properties.contains(property);
+	}
+
+	public ArrayList<Property<A>> getProperties(){
+		return properties;
+	}
+	
+    public void unbind() {
+    	if(visibilityBindings != null) visibilityBindings.unbind();
+    	
+    	for(int i = 0; i<properties.size(); ++i) {
+    		properties.get(i).removeListener(listeners.get(i));        		
+    	}
+    	
+    	listeners.clear();
+    }
+    
+    public void rebind() { 
+    	if(originListeners == null) {
+    		originListeners = new ArrayList<>();
+    		
+    		for(Property<A> prop: properties) {
+    			originListeners.add(new ChangeListener<A>() {
+    				@Override
+    				public void changed(ObservableValue<? extends A> observable, A oldValue, A newValue) {
+    					for(Property<A> prop_: properties) {
+    						if(prop != prop_) prop_.setValue(newValue);
+    					}
+    				}
+    			});
+    		}
+    	}
+    	
+		listeners = addFlaggedChangeListeners();
+		
+		if(visibilityBindings != null) visibilityBindings.rebind();
+    }
+
+    public Property<A> firstProperty(){
+    	if(isEmpty()) return null;
+    	else return properties.get(0);
+    }
+    
+    public void resetProperties(ArrayList<Property<A>> properties_) {
+		unbind();
+		properties.clear();
+		properties.addAll(properties_);
+		originListeners.clear();
+		originListeners = null;
+		rebind();
+		
+		if(visibilityBindings != null) {
+			ArrayList<Property<Boolean>> pubPRoperties = new ArrayList<>();
+			for(Property<A> prop: properties_)
+				pubPRoperties.add(((Shareable)prop).getPublicProperty());
+			
+			visibilityBindings.resetProperties(pubPRoperties);
+		}
+    }
+    
+	public void add(Property<A> property) {
+		unbind();
+		properties.add(property);
+		rebind();
+		
+		if(visibilityBindings != null) visibilityBindings.add(((Shareable)property).getPublicProperty());
+	}
+	
+	public void remove(Property<A> property) {
+		unbind();
+		properties.remove(property);
+		rebind();
+		
+		if(visibilityBindings != null) visibilityBindings.remove(((Shareable)property).getPublicProperty());
+	}
+    
+	public boolean isEmpty() {
+		return properties.isEmpty();
+	}
+	
+    protected ArrayList<LockedChangeListener> addFlaggedChangeListeners(){
+    	ArrayList<LockedChangeListener> newlisteners = new ArrayList<>();
+    	
+    	int i = 0;
+    	for(Property<A> prop: properties) {
+    		ChangeListener<A> updateProperty = originListeners.get(i++);
+    		LockedChangeListener listener = new LockedChangeListener(updateProperty);
+            newlisteners.add(listener);
+            
+            prop.addListener(listener);
+    	}
+    	        
+        return newlisteners;
+    }
+    
+        
+	class LockedChangeListener implements ChangeListener<A> {
+		protected boolean alreadyCalled = false;
+		protected ChangeListener<A> updateProperty = null;
+		
+		LockedChangeListener(ChangeListener<A> updateProperty){
+			this.updateProperty = updateProperty;
+		}
+		
+        @Override 
+        public void changed(ObservableValue<? extends A> observable, A oldValue, A newValue) {
+            if(alreadyCalled) return;
+            try {
+            	for(GroupBinding<A>.LockedChangeListener listener: listeners) {
+            		listener.alreadyCalled = true;
+            	}
+               // alreadyCalled = true;
+                updateProperty.changed(observable, oldValue, newValue);
+            }
+            finally { 
+            	for(GroupBinding<A>.LockedChangeListener listener: listeners) {
+            		listener.alreadyCalled = false;
+            	}
+            }
+        }
+	}
+    
+}
diff --git a/src/fr/inria/structgraphics/ui/utils/PropertyCloner.java b/src/fr/inria/structgraphics/ui/utils/PropertyCloner.java
new file mode 100644
index 0000000000000000000000000000000000000000..0466a1d23ebc4096d190a6412462ffc80d6b6df5
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/utils/PropertyCloner.java
@@ -0,0 +1,7 @@
+package fr.inria.structgraphics.ui.utils;
+
+import javafx.beans.property.Property;
+
+public class PropertyCloner {
+
+}
diff --git a/src/fr/inria/structgraphics/ui/utils/SortedMarkSet.java b/src/fr/inria/structgraphics/ui/utils/SortedMarkSet.java
new file mode 100644
index 0000000000000000000000000000000000000000..bac68b0952c25d5dc455b02b345e69a8e37a2c2b
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/utils/SortedMarkSet.java
@@ -0,0 +1,24 @@
+package fr.inria.structgraphics.ui.utils;
+
+import java.util.Comparator;
+import java.util.TreeSet;
+
+import fr.inria.structgraphics.graphics.Mark;
+
+public class SortedMarkSet extends TreeSet<Mark> {
+	
+	public SortedMarkSet(boolean xaxis) {
+		super(new Comparator<Mark>() {
+			@Override
+			public int compare(Mark mark1, Mark mark2) {		
+				if(xaxis) {
+					if(mark1.getCoords().getX() <= mark2.getCoords().getX()) return -1;
+					else return 1;
+				} else {
+					if(mark1.getCoords().getY() <= mark2.getCoords().getY()) return -1;
+					else return 1;
+				}
+			}
+		});
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/utils/Stats.java b/src/fr/inria/structgraphics/ui/utils/Stats.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7a11480a28cdf33607976b4b97cf0dd700d9ed7
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/utils/Stats.java
@@ -0,0 +1,27 @@
+package fr.inria.structgraphics.ui.utils;
+
+import java.util.List;
+
+public class Stats {
+	public double min = Double.MAX_VALUE, max = Double.MIN_VALUE, mean = 0, var = 0;
+	
+	public Stats(List<Double> numbers){
+		double sum = 0;
+
+		for(double num: numbers) {
+			sum += num;
+			min = Math.min(num, min);
+			max = Math.max(num, max);
+		}
+		
+		mean = sum / numbers.size();
+		
+		sum = 0;
+		for(double num: numbers) {
+			sum += Math.pow(num - mean, 2);
+		}
+		
+		var = sum / numbers.size();
+	}
+	
+}
\ No newline at end of file
diff --git a/src/fr/inria/structgraphics/ui/utils/Ticker.java b/src/fr/inria/structgraphics/ui/utils/Ticker.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf330c64e9ad30e657c39a35193bb5cb70d5456d
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/utils/Ticker.java
@@ -0,0 +1,152 @@
+package fr.inria.structgraphics.ui.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// Author: http://erison.blogspot.com/2011/07/algorithm-for-optimal-scaling-on-chart.html
+
+public class Ticker {
+
+	private double minPoint;
+	private double maxPoint;
+	private double maxTicks;
+	private double tickSpacing;
+	private double range;
+	private double niceMin;
+	private double niceMax;
+
+
+	public Ticker(double min, double max) {
+		this(min, max, 10, 20);
+	}
+	
+	/**
+	 * Instantiates a new instance of the NiceScale class.
+	 *
+	 * @param min the minimum data point on the axis
+	 * @param max the maximum data point on the axis
+	 * @param maxTicks the maximum number of ticks on the axis
+	 * @param minGap the minimum gap between two ticks
+	 */
+	public Ticker(double min, double max, double maxTicks, double minGap) {
+		this.maxTicks = Math.min(maxTicks, (max - min)/minGap); 
+		this.minPoint = min;
+		this.maxPoint = max;
+		calculate();
+	}
+
+	/**
+	 * Calculate and update values for tick spacing and nice
+	 * minimum and maximum data points on the axis.
+	 */
+	private void calculate() {
+		this.range = niceNum(maxPoint - minPoint, false);
+		this.tickSpacing = niceNum(range / (maxTicks - 1), true);
+		this.niceMin =
+				Math.floor(minPoint / tickSpacing) * tickSpacing;
+		this.niceMax =
+				Math.ceil(maxPoint / tickSpacing) * tickSpacing;
+	}
+
+	/**
+	 * Returns a "nice" number approximately equal to range Rounds
+	 * the number if round = true Takes the ceiling if round = false.
+	 *
+	 * @param range the data range
+	 * @param round whether to round the result
+	 * @return a "nice" number to be used for the data range
+	 */
+	private double niceNum(double range, boolean round) {
+		double exponent; /** exponent of range */
+		double fraction; /** fractional part of range */
+		double niceFraction; /** nice, rounded fraction */
+
+		exponent = Math.floor(Math.log10(range));
+		fraction = range / Math.pow(10, exponent);
+
+		if (round) {
+			if (fraction < 1.5)
+				niceFraction = 1;
+			else if (fraction < 3)
+				niceFraction = 2;
+			else if (fraction < 7)
+				niceFraction = 5;
+			else
+				niceFraction = 10;
+		} else {
+			if (fraction <= 1)
+				niceFraction = 1;
+			else if (fraction <= 2)
+				niceFraction = 2;
+			else if (fraction <= 5)
+				niceFraction = 5;
+			else
+				niceFraction = 10;
+		}
+
+		return niceFraction * Math.pow(10, exponent);
+	}
+
+	/**
+	 * Sets the minimum and maximum data points for the axis.
+	 *
+	 * @param minPoint the minimum data point on the axis
+	 * @param maxPoint the maximum data point on the axis
+	 */
+	public void setMinMaxPoints(double minPoint, double maxPoint) {
+		this.minPoint = minPoint;
+		this.maxPoint = maxPoint;
+		calculate();
+	}
+
+	/**
+	 * Sets maximum number of tick marks we're comfortable with
+	 *
+	 * @param maxTicks the maximum number of tick marks for the axis
+	 */
+	public void setMaxTicks(double maxTicks) {
+		this.maxTicks = maxTicks;
+		calculate();
+	}
+
+	/**
+	 * Gets the tick spacing.
+	 *
+	 * @return the tick spacing
+	 */
+	public double getTickSpacing() {
+		return tickSpacing;
+	}
+
+	/**
+	 * Gets the "nice" minimum data point.
+	 *
+	 * @return the new minimum data point for the axis scale
+	 */
+	public double getNiceMin() {
+		return niceMin;
+	}
+
+	/**
+	 * Gets the "nice" maximum data point.
+	 *
+	 * @return the new maximum data point for the axis scale
+	 */
+	public double getNiceMax() {
+		return niceMax;
+	}
+	
+	public List<Double> getTicks(){
+		double step = getTickSpacing();
+		double min = getNiceMin();
+		double max = getNiceMax();
+		
+		List<Double> ticks = new ArrayList<>();
+		
+		for(double f = min; f <= max; f+=step)
+			/*if(f >= minPoint)*/ ticks.add(f);
+				
+		return ticks;
+		
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/Canvas.java b/src/fr/inria/structgraphics/ui/viscanvas/Canvas.java
new file mode 100644
index 0000000000000000000000000000000000000000..fcd94df01a83e2a440066f5011931bddd0be5c56
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/Canvas.java
@@ -0,0 +1,49 @@
+package fr.inria.structgraphics.ui.viscanvas;
+
+import javafx.geometry.Pos;
+import javafx.scene.Group;
+import javafx.scene.layout.StackPane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.shape.Shape;
+
+public class Canvas extends StackPane {
+
+	private Group feedbackLayer;
+	private Rectangle rect;
+
+	public Canvas() {
+		alignmentProperty().set(Pos.TOP_LEFT);
+		feedbackLayer = new Group();
+	}
+	
+	public void setContent(Group group) {
+		getChildren().clear();
+		getChildren().add(group);
+				
+		getChildren().add(feedbackLayer);
+		rect = new Rectangle(getWidth(), getHeight());
+		rect.setStroke(null);
+		rect.setFill(Color.TRANSPARENT);
+	}
+
+	public void show(Shape shape, Shape cancelArea, Shape rectTrace) {
+		feedbackLayer.getChildren().clear();
+		if(cancelArea != null || shape != null || rectTrace != null) {
+			feedbackLayer.getChildren().add(rect);
+			
+			if(rectTrace != null) feedbackLayer.getChildren().add(rectTrace);
+			if(cancelArea != null) feedbackLayer.getChildren().add(cancelArea);
+			if(shape != null) feedbackLayer.getChildren().add(shape);
+		}
+	}	
+	
+	public void show(Shape shape) {
+		feedbackLayer.getChildren().add(shape);
+	}	
+
+	public void hide(Shape shape) {
+		feedbackLayer.getChildren().remove(shape);
+	}	
+
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/CanvasFrame.java b/src/fr/inria/structgraphics/ui/viscanvas/CanvasFrame.java
new file mode 100644
index 0000000000000000000000000000000000000000..465445b8e508d3372fabb369dfd963b629814adc
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/CanvasFrame.java
@@ -0,0 +1,500 @@
+package fr.inria.structgraphics.ui.viscanvas;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Optional;
+
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.MarkFactory;
+import fr.inria.structgraphics.graphics.SimpleMark;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.persistence.JsonDescription;
+import fr.inria.structgraphics.persistence.JsonObjectReader;
+import fr.inria.structgraphics.persistence.JsonObjectWriter;
+import fr.inria.structgraphics.persistence.JsonSpreadsheetWriterReader;
+import fr.inria.structgraphics.persistence.JsonWorkspaceWriter;
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.ui.DisplayPreferences;
+import fr.inria.structgraphics.ui.inspector.DisplayUtils;
+import fr.inria.structgraphics.ui.inspector.InspectorView;
+import fr.inria.structgraphics.ui.library.LibraryPane;
+import fr.inria.structgraphics.ui.spreadsheet.DataView;
+import fr.inria.structgraphics.ui.tools.CollectionCreationTool;
+import fr.inria.structgraphics.ui.tools.EraserTool;
+import fr.inria.structgraphics.ui.tools.FlowDrawingTool;
+import fr.inria.structgraphics.ui.tools.GroupCreationTool;
+import fr.inria.structgraphics.ui.tools.MarkSelection;
+import fr.inria.structgraphics.ui.tools.MultiplyTool;
+import fr.inria.structgraphics.ui.tools.SelectTool;
+import fr.inria.structgraphics.ui.tools.ShapeDrawingTool;
+import fr.inria.structgraphics.ui.tools.Tool;
+import javafx.animation.Transition;
+import javafx.beans.binding.Bindings;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Cursor;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Control;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.Separator;
+import javafx.scene.control.SplitPane;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.control.ToolBar;
+import javafx.scene.control.Tooltip;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.VBox;
+import javafx.stage.FileChooser;
+import javafx.stage.Stage;
+import javafx.util.Duration;
+import sun.security.x509.CRLReasonCodeExtension;
+
+public class CanvasFrame extends BorderPane {
+
+    public static final String STYLESHEETS = CanvasFrame.class.getResource("canvasframe.css").toExternalForm();
+	
+    public final static int LIB_WIDTH = 150;
+    
+	private Cursor visCursor = Cursor.DEFAULT;
+
+	VBox menus;
+
+	private SplitPane splitPane;
+	private BorderPane canvasPane;
+	private LibraryPane libraryPane;
+	
+	private Button clean, open, saveAs;
+	private Tool select, line, rect, circle, triangle, flowline, eraser, link, construct,  multiply, text;
+	private Tool selectedTool;
+	private ToggleButton showAnchors, showLibrary;
+	
+	private Canvas canvas;
+	private VisFrame visframe;
+	
+	private InspectorView inspector;
+	private DataView dataview;
+	
+	private SimpleMark draggable;
+	
+	private MarkSelection selectedMarks = new MarkSelection();
+	private Stage stage;
+	
+	public CanvasFrame(Stage stage) {
+		canvas = new Canvas();
+		this.stage = stage;
+
+		menus = new VBox();
+		setTop(menus);	
+
+		initTools();
+		setDrawingListeners();
+		
+		canvasPane = new BorderPane();
+		
+		libraryPane = new LibraryPane(this);
+		libraryPane.setMinWidth(LIB_WIDTH);
+		ScrollPane scroller = new ScrollPane();
+		scroller.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
+		scroller.setContent(libraryPane.getCanvas());
+		scroller.setStyle("-fx-background: #FFFFFF;");
+		
+		libraryPane.getCanvas().minWidthProperty().bind(Bindings.createDoubleBinding(() -> 
+        	scroller.getViewportBounds().getWidth(), scroller.viewportBoundsProperty()));
+		libraryPane.setCenter(scroller);
+		
+		splitPane = new SplitPane();
+        splitPane.setDividerPosition(0, 0);
+        splitPane.getItems().addAll(libraryPane, canvasPane);
+      
+        SplitPane.setResizableWithParent(libraryPane, false);
+        
+		splitPane.setId("splitpane");
+        
+        setCenter(splitPane);
+        
+        libraryPane.load();
+	}
+
+	public Stage getStage() {
+		return stage;
+	}
+	
+	private void initTools() {
+		select = new SelectTool(this);
+		line = new ShapeDrawingTool(this, ShapeProperty.Type.Line);
+		rect = new ShapeDrawingTool(this, ShapeProperty.Type.Rectangle);
+		circle = new ShapeDrawingTool(this, ShapeProperty.Type.Ellipse);
+		triangle = new ShapeDrawingTool(this, ShapeProperty.Type.Triangle);
+		flowline = new FlowDrawingTool(this);
+		text = new ShapeDrawingTool(this, ShapeProperty.Type.Text);
+		eraser = new EraserTool(this);
+		link = new CollectionCreationTool(this);
+		multiply = new MultiplyTool(this);
+		
+		construct = new GroupCreationTool(this);
+		
+		setActiveTool(select);		
+		select.setActive(true);
+	}
+	
+	public LibraryPane getLibrary() {
+		return libraryPane;
+	}
+	
+	public MarkSelection selected() {
+		return selectedMarks;
+	}
+	
+	public void setVisFrame(VisFrame frame) {
+		visframe = frame;
+		canvas.setContent(frame.getGroup());
+	}
+	
+	private void setDrawingListeners() {
+		canvas.setOnMouseMoved(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) { 
+				//if(select.getActive()) return;			
+				selectedTool.handleMove(event);
+			}
+		});
+		
+		canvas.setOnMousePressed(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) { 
+				//if(select.getActive()) return;			
+				selectedTool.handlePress(event);
+			}
+		});
+		
+		canvas.setOnMouseDragged(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {
+				//if(select.getActive()) return;			
+				selectedTool.handleDrag(event);
+			}
+		});
+		
+		canvas.setOnMouseReleased(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {
+				//if(select.getActive()) return;			
+				selectedTool.handleRelease(event);
+			}
+		});
+	}
+
+	
+	public VisFrame getVisFrame() {
+		return visframe;
+	}
+
+	public void setViews(InspectorView inspector, DataView dataview) {
+		this.inspector = inspector;
+		this.dataview = dataview;
+		
+		dataview.setSelector((SelectTool)select);
+		inspector.setSelector((SelectTool)select);
+	}
+	
+	public InspectorView getInspector() {
+		return inspector;
+	}
+	
+	public DataView getDataView() {
+		return dataview;
+	}
+	
+	public void setMenubars(Stage stage, Stage inspectStage) {
+
+		stage.getScene().cursorProperty().bindBidirectional(inspectStage.getScene().cursorProperty());
+		stage.getScene().cursorProperty().bindBidirectional(canvas.cursorProperty());
+
+		canvas.setOnMouseEntered(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {
+				stage.getScene().cursorProperty().set(visCursor);
+				//setCursor(visCursor); /// There is still a bug here, when i reactivate the window!!!!
+				//getCenter().setCursor(visCursor);
+			}
+		});
+
+		canvas.setOnMouseExited(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {
+				stage.getScene().cursorProperty().set(Cursor.DEFAULT);
+				//getCenter().setCursor(Cursor.DEFAULT);
+			}
+		});
+
+
+		// VisMenuBar menuBar = new VisMenuBar(stage, inspectStage, this, inspector, dataview);
+		// menus.getChildren().add(menuBar);
+
+		open = new Button("Open", new ImageView(DisplayUtils.getIcon("open-file")));
+		clean = new Button("Clean", new ImageView(DisplayUtils.getIcon("cleaning")));
+		saveAs = new Button("Save", new ImageView(DisplayUtils.getIcon("save")));
+		
+		showAnchors = new ToggleButton(null, new ImageView(DisplayUtils.getIcon("axis")));
+		showAnchors.setTooltip(new Tooltip("Show/Hide Anchors"));
+		
+		showLibrary = new ToggleButton(null, new ImageView(DisplayUtils.getIcon("library")));
+		showLibrary.setTooltip(new Tooltip("Library"));
+
+		select.getToggleButton().setTooltip(new Tooltip("Select"));
+		multiply.getToggleButton().setTooltip(new Tooltip("Replicate"));
+		link.getToggleButton().setTooltip(new Tooltip("Create Collection"));
+		construct.getToggleButton().setTooltip(new Tooltip("Create Group"));
+		eraser.getToggleButton().setTooltip(new Tooltip("Erase"));
+		
+		line.getToggleButton().setTooltip(new Tooltip("Draw Line"));
+		rect.getToggleButton().setTooltip(new Tooltip("Draw Rectangle"));
+		triangle.getToggleButton().setTooltip(new Tooltip("Draw Triangle"));
+		text.getToggleButton().setTooltip(new Tooltip("Create Textbox"));
+		flowline.getToggleButton().setTooltip(new Tooltip("Draw a Connection"));
+		
+		// From: https://www.flaticon.com/free-icon/cleaning_1215980
+
+		select.setActive(true);
+
+		ToolBar toolBar = new ToolBar(open, saveAs, clean,  new Separator(), select.getToggleButton(), multiply.getToggleButton(), link.getToggleButton(), construct.getToggleButton(), eraser.getToggleButton(),
+				new Separator(),
+		/*		groupshape.getToggleButton(),*/
+				line.getToggleButton(),
+				rect.getToggleButton(), circle.getToggleButton(), triangle.getToggleButton(), text.getToggleButton(), flowline.getToggleButton(),
+				new Separator(), showAnchors, showLibrary);
+		menus.getChildren().add(toolBar);
+
+		// Add Listeners
+		open.setOnAction(new EventHandler<ActionEvent>() {
+			public void handle(ActionEvent t) {
+				openSyntax(stage);
+			}
+		});    
+		
+		saveAs.setOnAction(new EventHandler<ActionEvent>() {
+			public void handle(ActionEvent t) {
+				saveWorkspace(stage);
+			}
+		});      
+
+
+		clean.setOnAction(
+				new EventHandler<ActionEvent>() {
+					@Override public void handle(ActionEvent e) {
+						Alert alert = new Alert(AlertType.CONFIRMATION);
+						alert.setTitle("Confirmation Dialog");
+						alert.setHeaderText(null);
+						alert.setContentText("Are you sure you want to clean the canvas?");
+
+						Optional<ButtonType> result = alert.showAndWait();
+						if (result.get() == ButtonType.OK){
+							cleanCanvas();
+						} else {
+							// ... user chose CANCEL or closed the dialog
+						}
+					}
+				});
+		
+		showAnchors.setSelected(true);
+		showAnchors.setOnAction(new EventHandler<ActionEvent>() {
+					@Override 
+					public void handle(ActionEvent e) {
+						visframe.showGroupInteractors(showAnchors.isSelected());
+					}
+				});
+		
+		showLibrary.setSelected(true);
+		showLibrary.setOnAction(new EventHandler<ActionEvent>() {
+					@Override 
+					public void handle(ActionEvent e) {
+						showLibrary(showLibrary.isSelected());
+					}
+				});
+	}
+
+	private void showLibrary(boolean show) {
+		if(show) {
+			Transition transition = new Transition() {
+			     {
+			         setCycleDuration(Duration.millis(150));
+			     }
+			     
+				@Override
+				protected void interpolate(double frac) {
+					libraryPane.setMinWidth(LIB_WIDTH*frac);
+					splitPane.setDividerPosition(0, 0);
+					
+					if(frac == 1) libraryPane.setMaxWidth(-1);
+				}
+				
+			};
+			transition.play();
+		}
+		else {
+			Transition transition = new Transition() {
+			     {
+			         setCycleDuration(Duration.millis(150));
+			     }
+			     
+				@Override
+				protected void interpolate(double frac) {
+					double w = LIB_WIDTH*(1 - frac);
+					libraryPane.setMinWidth(w);
+					splitPane.setDividerPosition(0, 0);		
+					
+					if(frac == 1) libraryPane.setMaxWidth(w);
+				}
+				
+			};
+			transition.play();
+			
+		}
+	}
+	
+	public Canvas getCanvas() {
+		return canvas;
+	}
+	
+	public void setCanvasCursor(Cursor cursor) {
+		visCursor = cursor;
+	}
+	
+	
+	public void setActiveTool(Tool tool) {
+		if(tool == null) tool = select;
+		
+		if(selectedTool != tool) { 	
+			if(selectedTool != null) selectedTool.setActive(false);
+			selectedTool = tool;
+			if(!selectedTool.getActive()) selectedTool.setActive(true);
+		}
+	}
+
+	private void openSyntax(Stage visStage) {
+		FileChooser fileChooser = new FileChooser();
+		fileChooser.setInitialDirectory(
+				new File("./json")
+				); 
+
+		fileChooser.getExtensionFilters().add(
+				new FileChooser.ExtensionFilter("Json", "*.json", "*.wrk")
+				);
+
+		fileChooser.setTitle("Open File (json or wrk)");
+		File file = fileChooser.showOpenDialog(visStage);
+		if(file == null) return;
+
+		JsonDescription descr = new JsonDescription(file);
+		if(descr.isWorkspace()) {
+			libraryPane.clear();
+			cleanCanvas();
+			libraryPane.load(descr.getLibraryArray(true));
+			JsonObjectReader.readChildrenFromJasonArray(visframe, descr.getVisArray(true));
+			inspector.update();
+			
+			// TODO: Add the spreadsheet
+			JsonSpreadsheetWriterReader.readSpreadsheetFromJasonObject(descr.getSpreadsheetArray(), visframe, dataview.getSpreadsheet());
+		}
+		else if(descr.isLibrary()) {
+			libraryPane.clear();
+			libraryPane.load(descr.getLibraryArray(false));
+		}
+		else {
+			JsonArray visArray = descr.getVisArray(false);
+			JsonObjectReader.readChildrenFromJasonArray(visframe, visArray);
+			inspector.update();
+		}
+	}
+
+	public void saveAs(Stage visStage, JsonObject visualizations) {
+		FileChooser fileChooser = new FileChooser();
+		fileChooser.setInitialDirectory(new File("./json")); 
+
+		fileChooser.getExtensionFilters().add(
+				new FileChooser.ExtensionFilter("Json", "*.json")
+				);
+
+		fileChooser.setTitle("Save As Json");	
+		File file = fileChooser.showSaveDialog(visStage);
+		if(file == null) return;
+		else {
+			try {
+				FileWriter writer = new FileWriter(file);
+				writer.write(JsonObjectWriter.fromObjectToReadableString(visualizations, 0).toString());
+				writer.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	public void saveWorkspace(Stage visStage) {
+		FileChooser fileChooser = new FileChooser();
+		fileChooser.setInitialDirectory(new File("./sessions")); 
+
+		fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Workspace", "*.wrk"));
+		fileChooser.setTitle("Save Workspace (Json)");
+		File file = fileChooser.showSaveDialog(visStage);
+		if(file == null) return;
+		else {
+			try {
+				FileWriter writer = new FileWriter(file);
+				JsonObject dataObject = JsonWorkspaceWriter.saveToJason(libraryPane.getComponents(), visframe.getComponents(), dataview.getSpreadsheet());
+				
+				writer.write(JsonObjectWriter.fromObjectToReadableString(dataObject, 0).toString());
+				
+				//writer.write(dataObject.toString());
+				writer.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	
+	private void cleanCanvas() {
+		VisFrame visFrame = MarkFactory.createVisFrame(DisplayPreferences.CANVAS_WIDTH, DisplayPreferences.CANVAS_HEIGHT);
+		visFrame.initProperties();
+
+		//  ScrollPane scroller = (ScrollPane)getCenter();
+		// scroller.setContent(new StackPane(visFrame.getGroup()));
+
+		setVisFrame(visFrame);
+
+		inspector.setVisualizationFrame(visFrame);
+		inspector.update();
+
+		dataview.reset();
+	}
+
+	public void setDraggable(SimpleMark mark) {
+		draggable = mark;
+	}
+	
+	public SimpleMark getDragged() {
+		return draggable;
+	}
+
+	public void setSketchArea(ScrollPane scroller) {
+		canvasPane.setCenter(scroller);
+	}
+
+	public Control getSplitPane() {
+		return splitPane;
+	}
+	
+	public void close() {
+		libraryPane.save();
+	}
+}
+
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/canvasframe.css b/src/fr/inria/structgraphics/ui/viscanvas/canvasframe.css
new file mode 100644
index 0000000000000000000000000000000000000000..af2b4fdd0685e5abb2ee46c722abf6e0e937bfeb
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/canvasframe.css
@@ -0,0 +1,34 @@
+/*
+ * Scenic View, 
+ * Copyright (C) 2012 Jonathan Giles, Ander Ruiz, Amy Fowler 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+.split-pane {
+    -fx-background-insets: 0, 1 0 1 0;
+    -fx-padding: 0 0 1 0;
+}
+.split-pane *.split-pane-divider{
+    -fx-padding: 0 1 0 0;
+    -fx-background-color: transparent, -fx-box-border;
+    -fx-background-insets: 0 -3 0 -3, 0;
+    -fx-border-color: null;
+}
+.split-pane *.horizontal-grabber {
+    -fx-padding: 0;
+    -fx-shape: "";
+}
+
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/CollectionPropertyStructure.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/CollectionPropertyStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c91d8901a00ff93df1ed105d52572793376ad8d
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/CollectionPropertyStructure.java
@@ -0,0 +1,441 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.types.ConstrainedDoubleProperty;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.NestedListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.Shareable;
+import fr.inria.structgraphics.ui.inspector.util.PropertyCloner;
+import fr.inria.structgraphics.ui.utils.GroupBinding;
+import javafx.beans.property.Property;
+
+public class CollectionPropertyStructure extends PropertyStructure {
+	
+	protected TreeMap<PropertyName, Property> shared;
+	protected List<Property> merged;
+	
+	protected TreeMap<PropertyName, DimensionalBinding> bindings;
+	protected TreeMap<PropertyName, GroupBinding> publicBindings;
+	
+	public CollectionPropertyStructure(Collection<Mark> marks) {
+		this(marks, new DefaultSharingStrategy());
+	}
+	
+	public CollectionPropertyStructure(Collection<Mark> marks, CollectionPropertyStructure structure) {		
+		properties = new TreeMap<>();
+		
+		for(Mark mark: marks) {
+			mark.addSelfProperties(true, properties);
+		}
+		
+		for(FlexibleListProperty property:properties.values())
+		{
+			if(property.getName().matches(PropertyName.getRegExpr("x")) ) {
+				id_x = new PropertyName(property.getName());
+				if(id_y != null) break;
+			}
+			else if(property.getName().matches(PropertyName.getRegExpr("y")) ) {
+				id_y = new PropertyName(property.getName());
+				if(id_x != null) break;
+			}
+		}
+		
+		common = new TreeSet<>();
+		common.addAll(structure.common);
+		
+		variable = new TreeSet<>();
+		variable.addAll(structure.variable);
+		
+		shared = new TreeMap<>();
+		bindings = new TreeMap<>();
+		
+		merge();
+		
+		bindGroupPublic(marks);
+	}
+	
+	
+	public CollectionPropertyStructure(Collection<Mark> marks, SortedSet<PropertyName> common, SortedSet<PropertyName> variable) {
+		properties = new TreeMap<>();
+		
+		for(Mark mark: marks) {
+			mark.addSelfProperties(true, properties);
+		}
+		
+		for(FlexibleListProperty property:properties.values())
+		{
+			if(property.getName().matches(PropertyName.getRegExpr("x")) ) {
+				id_x = new PropertyName(property.getName());
+				if(id_y != null) break;
+			}
+			else if(property.getName().matches(PropertyName.getRegExpr("y")) ) {
+				id_y = new PropertyName(property.getName());
+				if(id_x != null) break;
+			}
+		}
+		
+		this.common = common;
+		this.variable = variable;
+		
+		shared = new TreeMap<>();
+		bindings = new TreeMap<>();
+		
+		merge();
+		
+		bindGroupPublic(marks);
+	}
+	
+
+	public CollectionPropertyStructure(Collection<Mark> marks, SharingStrategy strategy) {
+		properties = new TreeMap<>();
+				
+		for(Mark mark: marks) {
+			mark.addSelfProperties(true, properties);
+		}
+		
+		for(FlexibleListProperty property:properties.values())
+		{
+			if(property.getName().matches(PropertyName.getRegExpr("x"))) {
+				id_x = new PropertyName(property.getName());
+				if(id_y != null) break;
+			}
+			else if(property.getName().matches(PropertyName.getRegExpr("y"))) {
+				id_y = new PropertyName(property.getName());
+				if(id_x != null) break;
+			}
+		}
+		
+		common = new TreeSet<>();
+		variable = new TreeSet<>();
+		shared = new TreeMap<>();
+		bindings = new TreeMap<>();
+		
+		strategy.share(properties.values(), common, variable);
+		merge();
+		
+		bindGroupPublic(marks);
+	}
+
+	//TODO
+	public void refresh(SharingStrategy strategy) {
+		SortedSet<PropertyName> common_ = new TreeSet<>();
+		SortedSet<PropertyName> variable_ = new TreeSet<>();
+		strategy.share(properties.values(), common_, variable_);
+				
+		for(PropertyName name: properties.keySet()) {
+			if(common.contains(name) && !common_.contains(name)) {
+				moveToVariable(name);
+			}
+			else if(common_.contains(name) && !common.contains(name)) {
+				moveToCommon(name);
+			}
+		}
+	}
+	
+	
+	private void bindGroupPublic(Collection<Mark> marks) {
+		if(marks.iterator().next() instanceof VisGroup) {
+			publicBindings = new TreeMap<>();
+			
+			for(FlexibleListProperty property:properties.values()) {
+				ArrayList<Property> pubproperties = new ArrayList<>();
+				for(Property p:property.getValue()) {
+					pubproperties.add(((Shareable)p).getPublicProperty());					
+				}
+				
+				// TODO: mode work needed....
+				GroupBinding binding = new GroupBinding(pubproperties, false);
+				publicBindings.put(property.getPropertyName(), binding);
+				binding.rebind();
+			}
+		}
+	}
+	
+	private void refreshPublicBindings() {
+		if(publicBindings != null) {
+			for(FlexibleListProperty property:properties.values()) {
+				ArrayList<Property> pubproperties = new ArrayList<>();
+				for(Property p: property.getValue()) {
+					pubproperties.add(((Shareable)p).getPublicProperty());					
+				}
+				
+				GroupBinding binding = publicBindings.get(property.getPropertyName());
+				binding.resetProperties(pubproperties);
+			}
+		}
+	}
+	
+	public void update(Mark mark, SharingStrategy strategy) {
+		mark.addSelfProperties(true, properties);
+		strategy.share(properties.values(), common, variable);
+		merge();
+	}
+
+	@Override
+	public void addMark(Mark mark, SharingStrategy strategy) {
+		mark.addSelfProperties(true, properties);
+		for(PropertyName key: common) {
+			destroyBindings(key);
+		}
+	
+//		common.clear();
+//		variable.clear();
+		shared.clear();
+		bindings.clear();
+		
+//		strategy.share(properties.values(), common, variable);
+		merge();
+		
+		refreshPublicBindings();
+	}
+	
+	@Override
+	public void addMark(Mark mark) {
+		mark.addSelfProperties(true, properties);
+
+		for(PropertyName name: common) {
+			FlexibleListProperty column = properties.get(name);
+			if(column.size() > 0) {
+				column.get(mark.getPos()).bindBidirectional(shared.get(name));			
+			}
+		}
+		
+		refreshPublicBindings();
+	}
+	
+	@Override
+	public void removeMark(Mark mark) {	
+		mark.removeSelfProperties(properties); // TODO: unnecessary to remove at the higher level groups
+						
+		rebuildBindings();
+		refreshPublicBindings();
+	}
+	
+	@Override
+	public void rebuildBindings() {
+		for(PropertyName key: common) {
+			destroyBindings(key);
+		}
+		
+		bindings.clear();
+		merge();
+	}
+			
+	
+	// TODO: not complete
+	public boolean areCommon(Property p1, Property p2) {
+		PropertyName name = new PropertyName(p1.getName());
+		if(common.contains(name) && p1.getValue().equals(p2.getValue())) return true;
+		else {
+			return false;
+		}
+	}
+	
+	@Override
+	public void moveToCommon(PropertyName name) {
+		if(common.contains(name)) return;
+		if(name.isHeight()) {
+			VisBody collection = container.getRootVirtualGroup();
+			if(collection instanceof LineConnectedCollection && 
+					((LineConnectedCollection)collection).hasConnections()) {
+				return;
+
+			}
+		}
+		
+		fixYConstraint(name);
+		fixXConstraint(name);
+		
+		variable.remove(name);
+		common.add(name);
+		merge();
+		
+		updateSiblings(name, true);
+		updateChildren(name);
+		
+		flagProperty.set(!flagProperty.get());
+		
+		if(name.isWidth() || name.isHeight()) {
+			FlexibleListProperty property = properties.get(name);
+			ConstrainedDoubleProperty prop = ((ConstrainedDoubleProperty)(property.flatten().get(0)));
+			
+			prop.updateValue(prop.getValue());
+		}
+	}
+	
+	@Override
+	public void moveToVariable(PropertyName name) {
+		if(variable.contains(name)) return;
+		
+		common.remove(name);
+		variable.add(name);
+		destroyBindings(name);
+		merge();
+		
+		updateSiblings(name, false);
+		
+		flagProperty.set(!flagProperty.get());
+		
+		if(name.isHeight() || name.isWidth()) {
+			FlexibleListProperty list = properties.get(name);
+			Property property = list.flatten().get(0);
+			ShapeMark mark = (ShapeMark)property.getBean();
+			if(mark.ratiolock.get()) { 
+				if(name.isWidth()) moveToVariable(new PropertyName(mark.height.getName()));
+				else moveToVariable(new PropertyName(mark.width.getName()));				
+			}
+		}
+	}
+
+	
+	private void updateChildren(PropertyName name){ // TODO: check how I can link heterogenuos groups!!!
+		if(container instanceof VisCollection) {
+			VisCollection vgroup = (VisCollection) container;
+			if(vgroup.getComponents().size() < 1) return;
+			Mark mark = vgroup.getComponents().get(0);
+			if(mark instanceof VisCollection) {
+				boolean incommon = ((VisCollection) mark).getChildPropertyStructure().common.contains(name);
+				for(int i = 1; i < vgroup.getComponents().size(); ++i) {
+					mark = vgroup.getComponents().get(i);
+					if(mark instanceof VisCollection && ((VisCollection) mark).getChildPropertyStructure().common.contains(name) != incommon) {
+						if(incommon) ((VisCollection) mark).getChildPropertyStructure().moveToCommon(name);
+						else ((VisCollection) mark).getChildPropertyStructure().moveToVariable(name);
+					}
+				}
+			}
+		}
+	}
+	
+	
+	private void updateSiblings(PropertyName name, boolean toCommon) {
+		if(container instanceof VisCollection) {
+			Container parent = ((VisCollection)container).getContainer();
+			if(parent instanceof VisCollection) {
+				VisCollection vgroup = ((VisCollection)parent);
+		//		if(vgroup.getChildPropertyStructure().getCommon().contains(name)) { // Removed!!!
+					
+					for(Mark mark: vgroup.getComponents()) {
+						if(mark instanceof VisCollection && mark != container) {
+							if(toCommon) ((VisCollection)mark).getChildPropertyStructure().moveToCommon(name);
+							else ((VisCollection)mark).getChildPropertyStructure().moveToVariable(name);
+							
+							//
+						}
+					}
+		//			}
+			}
+		}
+	}
+	
+	public List<Property> getMerged(){
+		List<Property> flat = new ArrayList<>();
+		
+		for(Property property : merged) {
+			if(property instanceof FlexibleListProperty && container instanceof VisCollection) {			
+				flat.add(((FlexibleListProperty)property).getCompact(((VisCollection) container).getComponentAt(0)));		
+			} else flat.add(property);
+		}
+		
+		return flat;
+	}
+	
+		
+	@Override
+	public void destroyAllBindings() {
+		for(PropertyName name:common) {
+			destroyBindings(name);
+		}
+	}
+	
+	
+	// TODO: I need to change the bindings mechanism
+	private void destroyBindings(PropertyName name) { // TODO:...
+		Property prop = shared.get(name);
+		
+		FlexibleListProperty column = properties.get(name);
+		if(column instanceof NestedListProperty) {
+			DimensionalBinding binding = bindings.get(name);
+			binding.destroy();
+			bindings.remove(name);
+		//	unmerge((NestedListProperty)column, id);
+		}
+		else if(column != null){
+			for(int i = 0; i < column.size(); ++i) {
+				column.get(i).unbindBidirectional(prop);
+			}
+		}
+
+		shared.remove(name);
+	}
+	
+	private void merge() {
+		merged = new ArrayList<>();
+		
+		for(PropertyName name: common) {
+			FlexibleListProperty column = properties.get(name);
+			if(column == null) continue;
+			if(column instanceof NestedListProperty) {
+				FlexibleListProperty prop = (FlexibleListProperty)shared.get(name);
+				if(prop != null) merged.add(prop);
+				else {
+					// Find the longest list as it has information for more items!!!
+					int max = 0;
+					int index = 0;
+					for(int i = 0; i < column.size(); ++i) {
+						int size = (((NestedListProperty)column).getPropertyList(i)).size();
+						if(size > max) {
+							index = i;
+							max = size;
+						}						
+					}
+					
+					prop = (FlexibleListProperty)PropertyCloner.replicate(column.get(index));
+					
+					merged.add(prop);
+					shared.put(name, prop);
+					bindings.put(name, new DimensionalBinding(this, column, prop.flattenFlex()));					
+				}
+			}
+			else {
+				Property prop = shared.get(name);
+				if(prop!= null) merged.add(prop);
+				else if(column.size() >  0) { 
+					prop = PropertyCloner.replicate(column.get(0));	
+					
+					merged.add(prop);
+					shared.put(name, prop); 
+					for(int i = 0; i < column.size(); ++i) {
+						column.get(i).bindBidirectional(prop);
+					}
+				}
+			}
+		}
+	}
+
+	
+	@Override
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("Common: ");
+		for(PropertyName name: common) buffer.append(properties.get(name).getName() + " =  " + properties.get(name).get() + ", ");
+		buffer.append("\nVariable: ");
+		for(PropertyName name: variable) buffer.append(properties.get(name).getName()+ " =  " + properties.get(name).get() + " ");
+		
+		return buffer.toString();
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/DefaultNestingStrategy.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/DefaultNestingStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..918a16c708f8a4b84b7982837351b0504add0774
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/DefaultNestingStrategy.java
@@ -0,0 +1,13 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.Mark;
+
+public class DefaultNestingStrategy extends NestingStrategy {
+	
+	public static Container getRoot(List<Mark> marks) {
+		return marks.get(0).getRoot();
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/DefaultSharingStrategy.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/DefaultSharingStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..95082307def42e911006e62a7394f2a438cfd1d0
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/DefaultSharingStrategy.java
@@ -0,0 +1,189 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeMap;
+
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.PositionCoords;
+import fr.inria.structgraphics.graphics.ReferenceCoords;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.graphics.XMarkComparator;
+import fr.inria.structgraphics.graphics.YMarkComparator;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.DoubleListProperty;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.NestedListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.utils.GroupBinding;
+import fr.inria.structgraphics.ui.viscanvas.groupings.Grouping.Type;
+import javafx.collections.ObservableList;
+import javafx.collections.transformation.SortedList;
+import javafx.scene.paint.Color;
+
+public class DefaultSharingStrategy extends SharingStrategy {
+
+	public final static double MAX_VARIANCE = 15;
+	
+	protected boolean isVariable(FlexibleListProperty column) {		
+		if(column.isEmpty()) return false;
+		else if(column.getHiddenProperty().get()) return true;
+		
+		if(column instanceof DoubleListProperty) {
+			double mean = ((DoubleListProperty) column).average();
+			if(column.getName().startsWith("thickness")) {
+				if(((DoubleListProperty) column).variance(mean) == 0) return false;
+				else return true;
+			}
+			else {
+				if(((DoubleListProperty) column).variance(mean) < MAX_VARIANCE) return false;
+				else return true;
+			}
+			
+		} 
+		else if(column instanceof NestedListProperty) {
+			List<FlexibleListProperty> transposed = ((NestedListProperty)column).transpose();
+
+			for(FlexibleListProperty listProperty:transposed) {
+				if(isVariable(listProperty)) return true;
+			}
+			return false;
+		}
+		else if(column.allEqual()) return false;
+		
+		return true;
+	}
+
+
+	/*
+	 * Create a VisCollection Object 
+	*/
+	
+	@Override
+	public VisCollection createCollection(ObservableList<Mark> marks) {
+		ReferenceStructureCreator creator = new ReferenceStructureCreator(marks, Type.Collection);
+		XReferenceStructure xstruct = creator.getXReferenceStructure();
+		YReferenceStructure ystruct = creator.getYReferenceStructure();
+				
+		SortedList<Mark> sorted; 
+		if(xstruct.isShared()) sorted = new SortedList<>(marks, new YMarkComparator());
+		else sorted = new SortedList<>(marks, new XMarkComparator());
+
+		VisCollection group = new LineConnectedCollection(DefaultNestingStrategy.getRoot(sorted), true);
+				//new VisCollection(DefaultNestingStrategy.getRoot(sorted));
+		group.setLevel(sorted.get(0).getLevel() + 1);
+		ReferenceCoords refCoords = new ReferenceCoords(RefX.Left, RefY.Bottom);
+		
+		group.setRefCoords(refCoords);
+				
+		PositionCoords coords = new PositionCoords(group, xstruct.getRefValue(), ystruct.getRefValue());
+		coords.xRef.set(RefX.Left);
+		coords.yRef.set(RefY.Bottom);
+		group.setCoords(coords);
+		
+		for(Mark mark: sorted) {
+			// TODO: Does it work?
+			if(!(mark instanceof VisBody)) {
+				mark.getCoords().xRef.set(xstruct.getRef());
+				mark.getCoords().yRef.set(ystruct.getRef());
+			}
+			
+			group.attach(mark, xstruct.isShared(), ystruct.isShared());
+		}
+		
+		group.refresh();
+		
+		CollectionPropertyStructure propertyStructure = new CollectionPropertyStructure(sorted, this);
+		group.setPropertyStructure(propertyStructure);
+		group.initProperties();
+		group.initVisibility();
+				
+		group.getConstraintXProperty().set(xstruct.constraint);
+		group.getConstraintYProperty().set(ystruct.constraint);
+		
+		propertyStructure.fixXSharing(); 
+		propertyStructure.fixYSharing(); 
+		
+		group.strokePaint.set(Color.color(.85, .8, .8, .5));
+		
+		group.getRoot().update();
+				
+		return group;
+	}
+
+
+	/*
+	 * Create a VisGroup object 
+	*/
+	@Override
+	public VisGroup createGroup(ObservableList<Mark> marks) {
+		// TODO I just repeat here the collection stuff, but this needs to change
+		ReferenceStructureCreator creator = new ReferenceStructureCreator(marks, Type.Group);
+		XReferenceStructure xstruct = creator.getXReferenceStructure();
+		YReferenceStructure ystruct = creator.getYReferenceStructure();
+		
+		SortedList<Mark> sorted; 
+		if(xstruct.isShared()) sorted = new SortedList<>(marks, new YMarkComparator());
+		else sorted = new SortedList<>(marks, new XMarkComparator());
+
+		VisGroup group = new VisGroup(DefaultNestingStrategy.getRoot(sorted), true);
+		group.setLevel(sorted.get(0).getLevel() + 1);
+		ReferenceCoords refCoords = new ReferenceCoords(RefX.Left, RefY.Bottom);
+		
+		group.setRefCoords(refCoords);
+				
+		PositionCoords coords = new PositionCoords(group, xstruct.getRefValue(), ystruct.getRefValue());
+		coords.xRef.set(RefX.Left);
+		coords.yRef.set(RefY.Bottom);
+		group.setCoords(coords);
+
+		for(Mark mark: sorted) {
+			// TODO: Does it work?
+			if(!(mark instanceof VisBody)) {
+		//		mark.getCoords().xRef.set(xstruct.getRef());
+		//		mark.getCoords().yRef.set(ystruct.getRef());
+			}
+			
+			group.attach(mark, xstruct.isShared(), ystruct.isShared());
+		}
+		
+		group.refresh();
+		
+		GroupPropertyStructure propertyStructure = new GroupPropertyStructure(sorted, this);
+		group.setPropertyStructure(propertyStructure);
+		group.initProperties();
+		group.initVisibility();
+		group.getConstraintXProperty().set(xstruct.constraint);
+		group.getConstraintYProperty().set(ystruct.constraint);
+		
+		propertyStructure.fixXSharing(); 
+		propertyStructure.fixYSharing(); 
+		
+		group.getRoot().update();
+		
+		return group;
+	}
+
+	
+	@Override
+	public void share(Map<PropertyName, FlexibleListProperty> properties, 
+			TreeMap<PropertyName, ArrayList<GroupBinding>> bindings, 
+			SortedSet<PropertyName> common, SortedSet<PropertyName> variable) {
+		
+		for(PropertyName name:properties.keySet()) {
+			FlexibleListProperty property = properties.get(name);
+			ArrayList<GroupBinding> groups = property.createGroupBindings();
+			
+			if(groups.size() < property.size()) {
+				bindings.put(name, groups);
+				common.add(name);
+			} else variable.add(name);
+		}
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/DimensionalBinding.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/DimensionalBinding.java
new file mode 100644
index 0000000000000000000000000000000000000000..656afe887a4f5bb63e9742ab235d91bce0a305ab
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/DimensionalBinding.java
@@ -0,0 +1,76 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import javafx.beans.property.Property;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
+public class DimensionalBinding {
+	private CollectionPropertyStructure propertyStructure;
+	private List<PropertyChangeListener> listeners = new ArrayList<>();
+	
+	public DimensionalBinding(CollectionPropertyStructure propertyStructure, FlexibleListProperty listProperty, FlexibleListProperty copies) {		
+		this.propertyStructure = propertyStructure;
+		
+		List<FlexibleListProperty> transposed = listProperty.transpose();
+		
+		int i = 0;
+		for(FlexibleListProperty sublist: transposed) {
+			addBindings(sublist, copies.get(i++)); 
+		}
+	}
+	
+	private void addBindings(FlexibleListProperty sublist, Property copy) {	
+		PropertyChangeListener listener = new PropertyChangeListener(sublist, copy);		
+		
+		for(Property property: sublist) { 
+			property.addListener(listener);
+			property.setValue(copy.getValue());
+		}
+		
+		copy.addListener(listener);
+		
+		listeners.add(listener);		
+	}
+
+	class PropertyChangeListener implements ChangeListener {
+		private FlexibleListProperty sublist;
+		private Property copy;
+		
+		public PropertyChangeListener(FlexibleListProperty sublist, Property copy) {
+			this.sublist = sublist;			
+			this.copy = copy;
+		}
+		
+		@Override
+		public void changed(ObservableValue observable, Object oldValue, Object newValue) { 
+		//	if(propertyStructure.isLocked()) return;
+			
+			for(Property property: sublist) {
+				if(observable != property) {
+					if(!property.getValue().equals(newValue)) property.setValue(newValue);
+				}
+			}
+			if(observable != copy && !copy.getValue().equals(newValue)) copy.setValue(newValue);
+		}
+		
+		public void disable(){
+			for(Property property: sublist) {
+				property.removeListener(this);
+			}
+			copy.removeListener(this);
+		}
+	}
+
+	public void destroy() {
+		for(PropertyChangeListener listener:listeners)
+			listener.disable();
+		
+		listeners.clear();
+	}
+			
+}
+
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/FlowConnection.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/FlowConnection.java
new file mode 100644
index 0000000000000000000000000000000000000000..bc6d68f5ef4038022dfb241fd667f743430a2ff9
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/FlowConnection.java
@@ -0,0 +1,143 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.ConnectionWeightProperty;
+import fr.inria.structgraphics.ui.utils.FlowConnectionBinding;
+
+public class FlowConnection implements Comparable<FlowConnection> {
+
+	private ShapeMark origin, destination;
+	public ConnectionWeightProperty weight;
+	private LineConnectedCollection collection;
+	private FlowConnections parent;
+	
+	public FlowConnection(LineConnectedCollection collection, ShapeMark origin, ShapeMark destination) {
+		this.collection = collection;
+		this.origin = origin;
+		this.destination = destination;
+		weight = new ConnectionWeightProperty(this);
+		weight.set(1);
+	}
+	
+	public void destroy() {
+		collection.removeConnection(this);
+		parent.remove(this);
+	}
+
+	public void detachFront() {
+		FlowConnectionBinding binding = destination.getFlowConnectionsBinding();
+		binding.removeInwardConnection(this);
+		
+		if(parent.hasInwardConnections(destination)) {
+			destination.height.updateValue(destination.height() - weight.get());
+		}
+	}
+	
+	public void detachBack() {
+		FlowConnectionBinding binding = origin.getFlowConnectionsBinding();
+		binding.removeOutwardConnection(this);
+		
+		if(parent.hasOutwardConnections(origin)) {
+			origin.height.updateValue(origin.height() - weight.get());
+		}
+		
+		origin.updateLabels();
+	}
+	
+	public double startX() {
+		double startX = origin.right();
+		
+		for(VisBody parent = (VisBody)origin.getContainer(); parent != collection; parent = (VisBody)parent.getContainer()) {
+			startX += parent.coords.getX();
+		}
+		
+		return startX;
+	}
+	
+	public double startY() {
+		double startY = -getOrigin().centerY();
+		
+		for(VisBody parent = (VisBody)origin.getContainer(); parent != collection; parent = (VisBody)parent.getContainer()) {
+			startY -= parent.coords.getY();
+		}
+
+		return startY;
+	}
+	
+	public double startYBottom() {		
+		return startY() - Math.abs(getOrigin().height())/2;
+	}
+	
+	public double endYBottom() {		
+		return endY() - Math.abs(getDestination().height())/2;
+	}
+	
+	public double endX() {
+		double endX = getDestination().left();
+		
+		for(VisBody parent = (VisBody)destination.getContainer(); parent != collection; parent = (VisBody)parent.getContainer()) {
+			endX += parent.coords.getX();
+		}
+		
+		return endX;
+	}
+	
+	public double endY() {
+		double endY = -getDestination().centerY();
+		
+		for(VisBody parent = (VisBody)destination.getContainer(); parent != collection; parent = (VisBody)parent.getContainer()) {
+			endY -= parent.coords.getY();
+		}
+		
+		return endY;
+	}
+	
+	public ShapeMark getOrigin() {
+		return origin;
+	}
+	
+	public ShapeMark getDestination() {
+		return destination;
+	}
+	
+	public ConnectionWeightProperty weightProperty() {
+		return weight;
+	}
+	
+	@Override
+	public int compareTo(FlowConnection conn) {
+		if(equals(conn)) return 0;
+		
+		int comp = origin.id.get().compareTo(conn.origin.id.get());
+		if(comp == 0) return destination.id.get().compareTo(conn.destination.id.get());
+		else return comp;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if(o instanceof FlowConnection) {
+			FlowConnection conn = (FlowConnection)o;
+			if(conn.origin == origin && conn.destination == destination) {
+				return true;
+			}
+		}
+		
+		return false;
+	}
+
+	public void setParent(FlowConnections flowConnections) {
+		this.parent = flowConnections;
+	}
+	
+	public LineConnectedCollection getCollection() {
+		return collection;
+	}
+
+
+	@Override
+	public int hashCode() { // Hmmm. This could generate a bug... very unlikely though...
+	    return origin.hashCode() + destination.hashCode();
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/FlowConnections.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/FlowConnections.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a8df56de9dacee78805e0c77d1a3bd0908a34d3
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/FlowConnections.java
@@ -0,0 +1,321 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import javafx.beans.property.Property;
+
+public class FlowConnections extends HashSet<FlowConnection> implements Comparator<FlowConnection>{
+
+	protected LineConnectedCollection collection;
+	
+	public FlowConnections(LineConnectedCollection collection) {
+		super();
+		this.collection = collection;
+	}
+			
+	// TODO: This is a very first draft...
+	public FlowConnection addConnection(ShapeMark origin, ShapeMark destination, boolean clever) {
+		FlowConnection conn = new FlowConnection(collection, origin, destination);
+		conn.setParent(this);
+		
+		if(!clever) {
+			add(conn);
+			return conn;
+		}
+		
+		if(!contains(conn)) {	
+			origin.lockListeners(true);
+			destination.lockListeners(true);
+			
+			if(!hasOutwardConnections(origin)) {	
+				if(!hasInwardConnections(origin) && !hasInwardConnections(destination)) {
+					if(hasOutwardConnections(destination)) {
+						conn.weightProperty().set(destination.height());
+						origin.height.updateValue(destination.height());
+					} else {
+						conn.weightProperty().set(origin.height());
+						destination.height.updateValue(origin.height());
+					}
+				} else {
+					conn.weightProperty().set(origin.height());
+					if(!hasInwardConnections(destination) /*&& !hasFromConnections(destination)*/) {
+						destination.lockListeners(false);
+						destination.height.updateValue(origin.height());
+						//Set<FlowConnection> fromDestination = from(destination);
+						//for(FlowConnection fo:fromDestination) w += fo.weightProperty().get();
+					}
+					else {
+						destination.height.updateValue(destination.height() + origin.height());
+					}
+				}	
+			} else { // NOT fully complete	
+				if(hasInwardConnections(destination)) {
+					Set<FlowConnection> fromOrigin = from(origin);
+					double w = 0;
+					for(FlowConnection fo:fromOrigin) w += fo.weightProperty().get();
+					double diff = origin.height() - w;
+					if(diff == 0) {
+						diff = 10;
+						conn.weightProperty().set(diff);
+						destination.height.updateValue(destination.height() + diff);
+						
+						//origin.lockListeners(false);
+						origin.height.updateValue(origin.height() + diff);
+					} else {
+						conn.weightProperty().set(diff);
+						destination.height.updateValue(destination.height() + diff);
+					}
+				}
+				else {
+					Set<FlowConnection> fromOrigin = from(origin);
+					double w = 0;
+					for(FlowConnection fo:fromOrigin) w += fo.weightProperty().get();
+					double diff = origin.height() - w;
+					
+					if(diff > 0) {
+						conn.weightProperty().set(diff);
+						destination.height.updateValue(diff);
+					} else {
+						conn.weightProperty().set(destination.height());
+						
+						//origin.lockListeners(false);
+						origin.height.updateValue(destination.height() + origin.height());						
+					}
+				}
+			}
+			
+			add(conn);
+			
+			origin.lockListeners(false);
+			destination.lockListeners(false);
+			
+			return conn;
+		}
+		else return null;
+	}
+		
+	public void removeConnection(FlowConnection conn) {
+		this.remove(conn);
+	}
+	
+	public void removeConnection(ShapeMark origin, ShapeMark destination) {
+		this.remove(new FlowConnection(collection, origin, destination));
+	}
+	
+	public void removeFrom(ShapeMark origin) {
+		Set<FlowConnection> connections = from(origin);
+		this.removeAll(connections);
+	}
+	
+
+	public void removeTo(ShapeMark destination) {
+		Set<FlowConnection> connections = to(destination);
+		this.removeAll(connections);
+	}
+	
+	
+	public boolean hasInwardConnections(ShapeMark shape) {
+		for(FlowConnection conn: this) {
+			if(conn.getDestination() == shape) return true;
+		}
+		
+		return false;
+	}
+	
+	public boolean hasOutwardConnections(ShapeMark shape) {
+		for(FlowConnection conn: this) {
+			if(conn.getOrigin() == shape) return true;
+		}
+		
+		return false;
+	}
+	
+	public Set<FlowConnection> from(ShapeMark origin){
+		TreeSet subset = new TreeSet<>();
+		
+		for(FlowConnection conn: this) {
+			if(conn.getOrigin() == origin)
+				subset.add(conn);
+		}
+		
+		return subset;
+	}
+	
+	
+	public Set<FlowConnection> to(ShapeMark destination){
+		TreeSet subset = new TreeSet<>();
+		
+		for(FlowConnection conn: this) {
+			if(conn.getDestination() == destination)
+				subset.add(conn);
+		}
+		
+		return subset;
+	}
+	
+	/*
+	 * This is used for the spreadsheet
+	 */
+	public Map<PropertyName, FlexibleListProperty> getCompactVariableList(ArrayList<PropertyName> names){
+		Map<PropertyName, FlexibleListProperty> flat = new TreeMap<>(); 
+
+		Set<FlowConnection> connections = this.sortByX();
+		
+		if(names.contains(new PropertyName("id"))) {
+			List<Property> ids = new ArrayList<>();
+			for(FlowConnection conn: connections) {
+				List<Property> source_destination = new ArrayList<>();
+				source_destination.add(conn.getOrigin().id);
+				source_destination.add(conn.getDestination().id);
+				ids.add(FlexibleListProperty.createList(collection, source_destination));
+			}
+			FlexibleListProperty connectionListProperty = FlexibleListProperty.createList(collection, ids);				
+			flat.put(connectionListProperty.getPropertyName(), connectionListProperty);
+		}
+		if(names.contains(new PropertyName("weight"))) {
+			List<Property> weights = new ArrayList<>();
+			for(FlowConnection conn: connections) {
+				weights.add(conn.weightProperty());
+			}
+			FlexibleListProperty weightListProperty = FlexibleListProperty.createList(collection, weights);				
+			flat.put(weightListProperty.getPropertyName(), weightListProperty);
+		}
+				
+		return flat;
+	}
+
+	
+	/*
+	 * This is used for the inspector
+	 */
+
+	public Map<PropertyName, FlexibleListProperty> getVariableList(){ 
+		Map<PropertyName, FlexibleListProperty> flat = new TreeMap<>(); 
+		
+		// 1: First, we add the IDs of all nodes!!!
+		//FlexibleListProperty ids = FlexibleListProperty.createList(bean, properties);
+		List<Property> ids1 = new ArrayList<>();
+		List<Property> ids2 = new ArrayList<>();
+		List<Property> weights = new ArrayList<>();
+		for(FlowConnection conn: this.sortByX()) {
+			ids1.add(conn.getOrigin().id);
+			ids2.add(conn.getDestination().id);
+			weights.add(conn.weightProperty());
+		}
+
+		FlexibleListProperty originListProperty = FlexibleListProperty.createList(collection, ids1);	
+		FlexibleListProperty destinationListProperty = FlexibleListProperty.createList(collection, ids2);	
+		FlexibleListProperty weightListProperty = FlexibleListProperty.createList(collection, weights);	
+		
+		flat.put(/*originListProperty.getPropertyName()*/new PropertyName("source"), originListProperty);
+		flat.put(/*destinationListProperty.getPropertyName()*/new PropertyName("destination"), destinationListProperty);
+		flat.put(weightListProperty.getPropertyName(), weightListProperty);
+		
+		// TO add the extra property for weights
+		
+		return flat;
+	}
+
+	// Sort all connections by the X coordinate of their origin, destination
+	public Set<FlowConnection> sortByX(){
+		TreeSet<FlowConnection> subset = new TreeSet<FlowConnection>(new Comparator<FlowConnection>() {
+
+			@Override
+			public int compare(FlowConnection conn1, FlowConnection conn2) {
+				ShapeMark origin1 = conn1.getOrigin();
+				ShapeMark origin2 = conn2.getOrigin();
+				
+				if(origin1 != origin2) {
+					double x1 = origin1.coords.getX();
+					double x2 = origin2.coords.getX();
+					
+					if(x1 < x2) return -1;
+					else if(x1 > x2) return 1;
+					else if (origin1.coords.getY() <= origin2.coords.getY()) return -1;
+					else return 1;
+				} else {
+					ShapeMark dest1 = conn1.getDestination();
+					ShapeMark dest2 = conn2.getDestination();
+					
+					if(dest1 == dest2) return 0;
+					
+					double x1 = dest1.coords.getX();
+					double x2 = dest2.coords.getX();
+					
+					if(x1 < x2) return -1;
+					else if(x1 > x2) return 1;
+					else if (dest1.coords.getY() <= dest2.coords.getY()) return -1;
+					else return 1;
+				}
+			}
+		});
+		
+		for(FlowConnection conn: this) {
+			subset.add(conn);
+		}
+		
+		return subset;
+	}
+	
+	
+	// Sort all connections by the Y coordinate of their origin, destination
+	// Also, rest
+	public Set<FlowConnection> sortByY(){
+		TreeSet<FlowConnection> subset = new TreeSet<FlowConnection>(selfAsComparator());
+		
+		for(FlowConnection conn: this) {
+			subset.add(conn);
+		}
+		
+		return subset;
+	}
+	
+	private Comparator<FlowConnection> selfAsComparator(){
+		return this;
+	}
+	
+	@Override
+	public int compare(FlowConnection conn1, FlowConnection conn2) {
+		ShapeMark origin1 = conn1.getOrigin();
+		ShapeMark origin2 = conn2.getOrigin();
+		
+		if(origin1 != origin2) {
+			double y1 = origin1.getYIn(collection);//origin1.coords.getY();
+			double y2 = origin2.getYIn(collection);//origin2.coords.getY();
+			
+			if(y1 < y2) return 1;
+			else if(y1 > y2) return -1;
+			else if (origin1.getXIn(collection) <= origin2.getXIn(collection)) return 1;
+			//else if (origin1.coords.getX() <= origin2.coords.getX()) return 1;
+			else return -1;
+		} else {
+			ShapeMark dest1 = conn1.getDestination();
+			ShapeMark dest2 = conn2.getDestination();
+			
+			if(dest1 == dest2) return 0;
+			
+			double y1 = dest1.getYIn(collection);//dest1.coords.getY();
+			double y2 = dest2.getYIn(collection);//dest2.coords.getY();
+			
+			if(y1 < y2) return 1;
+			else if(y1 > y2) return -1;
+			else if (dest1.getXIn(collection) <= dest2.getXIn(collection)) return 1;
+			//else if (dest1.coords.getX() <= dest2.coords.getX()) return 1;
+			else return -1;
+		}
+	}
+	
+	
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/GroupPropertyStructure.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/GroupPropertyStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..f76643d9176df0444ec37f26644b3e4733c00d6c
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/GroupPropertyStructure.java
@@ -0,0 +1,266 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.types.ConstrainedDoubleProperty;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.Shareable;
+import fr.inria.structgraphics.ui.utils.GroupBinding;
+import javafx.beans.property.Property;
+
+public class GroupPropertyStructure extends PropertyStructure {
+
+	protected TreeMap<PropertyName, ArrayList<GroupBinding>> bindings = new TreeMap<>();
+	
+	public GroupPropertyStructure(Collection<Mark> marks) {
+		this(marks, new DefaultSharingStrategy());
+	}
+	
+	public GroupPropertyStructure(Collection<Mark> marks, SharingStrategy strategy) {
+		properties = new TreeMap<>();
+				
+		for(Mark mark: marks) {
+			mark.addSelfProperties(false, properties);
+			
+			if(mark instanceof VisGroup) {
+				((VisGroup) mark).getChildPropertyStructure().makeAllVariable();
+			}
+		}
+		
+		for(FlexibleListProperty property:properties.values())
+		{
+			if(property.getName().matches(PropertyName.getRegExpr("x"))) {
+				id_x = new PropertyName(property.getName());
+				if(id_y != null) break;
+			}
+			else if(property.getName().matches(PropertyName.getRegExpr("y"))) {
+				id_y = new PropertyName(property.getName());
+				if(id_x != null) break;
+			}
+		}
+
+		common = new TreeSet<>();
+		variable = new TreeSet<>();
+		strategy.share(properties, bindings, common, variable);		
+	}
+		
+	public GroupPropertyStructure(Collection<Mark> marks, GroupPropertyStructure structure) {
+		properties = new TreeMap<>();
+				
+		for(Mark mark: marks) {
+			mark.addSelfProperties(false, properties);
+		}
+		
+		for(FlexibleListProperty property:properties.values())
+		{
+			if(property.getName().matches(PropertyName.getRegExpr("x"))) {
+				id_x = new PropertyName(property.getName());
+				if(id_y != null) break;
+			}
+			else if(property.getName().matches(PropertyName.getRegExpr("y"))) {
+				id_y = new PropertyName(property.getName());
+				if(id_x != null) break;
+			}
+		}
+
+		common = new TreeSet<>();
+		common.addAll(structure.common);
+		variable = new TreeSet<>();
+		variable.addAll(structure.variable);
+		
+		rebuildBindings();
+	}
+	
+	
+	public GroupPropertyStructure(Collection<Mark> marks, SortedSet<PropertyName> common, SortedSet<PropertyName> variable) {
+		properties = new TreeMap<>();
+		
+		for(Mark mark: marks) {
+			mark.addSelfProperties(false, properties);
+		}
+		
+		for(FlexibleListProperty property:properties.values())
+		{
+			if(property.getName().matches(PropertyName.getRegExpr("x")) ) {
+				id_x = new PropertyName(property.getName());
+				if(id_y != null) break;
+			}
+			else if(property.getName().matches(PropertyName.getRegExpr("y")) ) {
+				id_y = new PropertyName(property.getName());
+				if(id_x != null) break;
+			}
+		}
+		
+		this.common = common;
+		this.variable = variable;
+		// rebuildBindings();
+	}
+	
+	
+	public ArrayList<GroupBinding> getGroups(PropertyName name) {
+		return bindings.get(name);
+	}
+	
+	public ArrayList<Property> getBindingsOf(Property property){
+		ArrayList<GroupBinding> groups = bindings.get(new PropertyName(property.getName()));
+		for(GroupBinding group: groups) {
+			if(group.contains(property))
+				return group.getProperties();
+		}
+		
+		return null;
+	}
+	
+	@Override
+	public void addMark(Mark mark, SharingStrategy strategy) {
+		this.addMark(mark);
+	}
+
+	@Override
+	public void addMark(Mark mark) {
+		mark.addSelfProperties(false, properties);
+		List<Property> props = mark.getProperties();
+
+		for(Property prop: props) {
+			PropertyName name = new PropertyName(prop.getName());
+			if(variable.contains(name)) break;
+			
+			ArrayList<GroupBinding> groups = bindings.get(name);
+			if(!groups.isEmpty()) {
+				for(GroupBinding group: groups) {
+					if(group.hasValue(prop)) {
+						group.add(prop);
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	@Override
+	public void removeMark(Mark mark) {
+		mark.removeSelfProperties(properties);
+		List<Property> props = mark.getProperties();
+
+		for(Property prop: props) {
+			PropertyName name = new PropertyName(prop.getName());
+			if(variable.contains(name)) break;
+			
+			ArrayList<GroupBinding> groups = bindings.get(name);
+			if(!groups.isEmpty()) {
+				GroupBinding group_ = null;
+				
+				for(GroupBinding group: groups) {
+					if(group.hasValue(prop)) {
+						group.remove(prop);
+						if(group.isEmpty()) group_ = group;
+						break;
+					}
+				}
+				
+				if(group_ != null) groups.remove(group_); 
+			}
+		}
+	}
+
+	public void setBindings(TreeMap<PropertyName, ArrayList<GroupBinding>> bindings) {
+		this.bindings = bindings;
+	}
+	
+	@Override
+	public void destroyAllBindings() {
+		for(ArrayList<GroupBinding> groups:bindings.values()) {
+			for(GroupBinding group:groups) {
+				group.unbind();
+			}
+			groups.clear();
+		}
+		
+		bindings.clear();
+	}
+
+	@Override
+	public void rebuildBindings() {
+		for(PropertyName name: properties.keySet()) {		
+			if(common.contains(name)) {
+				FlexibleListProperty prop = properties.get(name);
+				bindings.put(name, prop.createGroupBindings());	
+			}
+		}
+	}
+
+	@Override
+	public void moveToCommon(PropertyName name) {
+		if(common.contains(name)) return;
+		
+		// TODO: ?????
+		fixYConstraint(name);
+		fixXConstraint(name);
+		
+		variable.remove(name);
+		common.add(name);
+		
+		FlexibleListProperty prop = properties.get(name);
+		bindings.put(name, prop.createGroupBindings());	
+		
+		flagProperty.set(!flagProperty.get());		
+		
+		if(name.isWidth() || name.isHeight()) {
+			FlexibleListProperty property = properties.get(name);
+			ConstrainedDoubleProperty dprop = ((ConstrainedDoubleProperty)(property.flatten().get(0)));
+			
+			dprop.updateValue(dprop.getValue());
+		}
+	}
+
+	@Override
+	public void moveToVariable(PropertyName name) {
+		if(variable.contains(name)) return;
+		common.remove(name);
+		variable.add(name);
+		
+		ArrayList<GroupBinding> groups = bindings.get(name);
+		if(groups != null) {
+			for(GroupBinding group:groups) group.unbind();
+			groups.clear();
+			bindings.remove(name);
+		}
+	
+		flagProperty.set(!flagProperty.get());
+		
+	}
+	
+	public void makeAllVariable() {
+		for(PropertyName propName:properties.keySet()) {
+			if(common.contains(propName)) moveToVariable(propName);
+		}
+	}
+	
+	public Collection<Property> getFlattenedProperties(){
+		Collection<Property> flattened = new ArrayList<>();
+		
+		for(PropertyName name: properties.keySet()) {
+			FlexibleListProperty property = properties.get(name);
+			if(common.contains(name)) {
+				ArrayList<Property> propertyList = new ArrayList<>();
+				
+				ArrayList<GroupBinding> groups = bindings.get(name);
+				for(GroupBinding group: groups) {
+					if(!group.isEmpty()) propertyList.add(group.firstProperty());
+				}
+				
+				flattened.add(FlexibleListProperty.createList(/*property.getBean()*/ container, propertyList));
+			} else flattened.add(property);
+		}
+		
+		return flattened;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/Grouping.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/Grouping.java
new file mode 100644
index 0000000000000000000000000000000000000000..188e184407b3544d5ebd65d90a7d2ca0d05a7b86
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/Grouping.java
@@ -0,0 +1,21 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import fr.inria.structgraphics.graphics.Mark;
+import javafx.collections.ObservableList;
+
+public class Grouping {
+	
+	public enum Type {Collection, Group} 
+	
+	protected Mark markGroup;
+	protected CollectionPropertyStructure structure;
+	
+	public Grouping(ObservableList<Mark> marks, Type type) {
+		if(type == Type.Collection) markGroup = new DefaultSharingStrategy().createCollection(marks);
+		else markGroup = new DefaultSharingStrategy().createGroup(marks);
+	}
+		
+	public Mark getGroup() {
+		return markGroup;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/NestingStrategy.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/NestingStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..9cade6f25d8ba0d88b128fbad97ceef7cf0d96b9
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/NestingStrategy.java
@@ -0,0 +1,5 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+public abstract class NestingStrategy {
+
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/NestingStructure.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/NestingStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..cae854058d4277204cf39b14f6b5d54b9bd46e00
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/NestingStructure.java
@@ -0,0 +1,15 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import java.util.ArrayList;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.PositionCoords;
+
+public class NestingStructure {
+	protected PositionCoords containerCoords, childrenCoords;
+	
+	public NestingStructure(ArrayList<Mark> marks, NestingStrategy strategy) {
+		
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/PropertyStructure.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/PropertyStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a11a65c256f3c0bc16fabe2ea0aa44f351baf20
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/PropertyStructure.java
@@ -0,0 +1,269 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleBooleanProperty;
+
+public abstract class PropertyStructure {	
+	
+	protected BooleanProperty flagProperty = new SimpleBooleanProperty(true);
+
+	protected Map<PropertyName, FlexibleListProperty> properties;
+	protected VisBody container;
+	protected PropertyName id_x = null, id_y = null;
+	protected SortedSet<PropertyName> common, variable;
+	
+	public abstract void addMark(Mark mark, SharingStrategy strategy);
+	public abstract void addMark(Mark mark);
+	public abstract void removeMark(Mark mark);
+	public abstract void destroyAllBindings();
+	public abstract void rebuildBindings();
+	public abstract void moveToCommon(PropertyName propertyName);
+	public abstract void moveToVariable(PropertyName name);
+	
+	public boolean isXShared() {
+		return id_x != null && common.contains(id_x);
+	}
+
+	public boolean isYShared() {
+		return id_y != null && common.contains(id_y);
+	}
+	
+	public FlexibleListProperty getXListProperty() {
+		return properties.get(id_x);
+	}
+	
+	public FlexibleListProperty getYListProperty() {
+		return properties.get(id_y);
+	}
+	
+	public Map<PropertyName, FlexibleListProperty> getProperties(){
+		return properties;
+	}
+	
+	public FlexibleListProperty getProperty(PropertyName name) {
+		return properties.get(name);
+	}
+	
+	public boolean isEmpty() {
+		return properties.isEmpty();
+	}
+	
+	
+	public Property getCompactFlat(PropertyName name) {
+		Property property = properties.get(name);
+		
+		if(property instanceof FlexibleListProperty && container instanceof VisCollection) {					
+			Property prop = ((FlexibleListProperty)property).getCompact(((VisCollection) container).getComponentAt(0));
+			if(prop instanceof FlexibleListProperty) return ((FlexibleListProperty)prop).get(0);
+			else return prop;
+		} else return property;
+	}
+	
+	public static PropertyStructure create(Collection<Mark> marks, PropertyStructure structure) {
+		if(structure instanceof CollectionPropertyStructure) return new CollectionPropertyStructure(marks, (CollectionPropertyStructure)structure);
+		else return new GroupPropertyStructure(marks, (GroupPropertyStructure)structure); // TODO
+	}
+	
+	public void setContainer(VisBody container) {
+		this.container = container;
+	}
+	
+	public BooleanProperty getFlagProperty() {
+		return flagProperty;
+	}
+	
+	public SortedSet<PropertyName> getVariable(){
+		return variable;
+	}
+	
+	public SortedSet<PropertyName> getCommon(){
+		return common;
+	}
+	
+	public Set<PropertyName> getNames(){
+		return properties.keySet();
+	}
+		
+	public Collection<Property> getCommonProperties(){
+		ArrayList<Property> list = new ArrayList<>();
+		for(PropertyName name:common) {
+			list.add(properties.get(name));
+		}
+		
+		return list;
+	}
+	
+	
+	public Map<PropertyName, FlexibleListProperty> getVariableList(){
+		Map<PropertyName, FlexibleListProperty> flat = new TreeMap<>();
+		
+		for(PropertyName name: variable) {
+			FlexibleListProperty list = properties.get(name);
+			
+			if(list != null && list.getPublicProperty().get() && !list.getHiddenProperty().get())
+				flat.put(name, (FlexibleListProperty)list.getCompact(container));
+		}
+		
+		return flat;
+	}
+	
+	
+	public Map<PropertyName, FlexibleListProperty> getVariableList(Collection<PropertyName> names){
+		Map<PropertyName, FlexibleListProperty> flat = new TreeMap<>();
+		
+		for(PropertyName name: names) {
+			FlexibleListProperty list = properties.get(name);
+			
+			if(list != null && list.getPublicProperty().get() && !list.getHiddenProperty().get())
+				flat.put(name, (FlexibleListProperty)list.getCompact2(container));
+		}
+		
+		return flat;
+	}
+	
+
+	private void addIDColumns(Map<PropertyName, FlexibleListProperty> flat, Collection<PropertyName> names) {
+		int maxLevel = container.getLevel();
+		int minLevel = container.getBottomLevel();
+		
+		for(int level = minLevel; level<maxLevel; ++level) {
+			List<Property> ids = new ArrayList<>();
+			container.addIDs(ids, level);
+			FlexibleListProperty idsListProperty = FlexibleListProperty.createList(container, ids);	
+			if(names == null || names.contains(idsListProperty.getPropertyName())) flat.put(idsListProperty.getPropertyName(), idsListProperty);
+		}
+	}
+	
+	public Map<PropertyName, FlexibleListProperty> getFullVariableList(){
+		Map<PropertyName, FlexibleListProperty> flat = new TreeMap<>(); 
+		
+		addIDColumns(flat, null);
+				
+		for(FlexibleListProperty propertyList: properties.values()) { 
+			if(propertyList.varies(container) && propertyList.getPublicProperty().get() 
+					&& !propertyList.getHiddenProperty().get()) {				
+				flat.put(propertyList.getPropertyName(), (FlexibleListProperty)propertyList.getExtended());				
+			}
+		}
+				
+		return flat;
+	}
+	
+	
+	public Map<PropertyName, FlexibleListProperty> getFullVariableList(Collection<PropertyName> names){
+		Map<PropertyName, FlexibleListProperty> flat = new TreeMap<>(); 
+
+		addIDColumns(flat, names);
+		
+		for(PropertyName name: names) {
+			FlexibleListProperty list = properties.get(name);
+			
+			if(list != null && list.getPublicProperty().get() && !list.getHiddenProperty().get())
+				flat.put(name, (FlexibleListProperty)list.getExtended());
+		}
+						
+		return flat;
+	}
+	
+	public void fixYSharing() {		
+		if(container.getComponents().get(0) instanceof VisCollection) {
+			VisBody child = (VisBody) container.getComponents().get(0);
+			PropertyName yproperty = new PropertyName(child.getComponents().get(0).coords.y.getName());
+
+			if(child.constraintYProperty.get() != Constraint.None && !variable.contains(yproperty)) {
+				moveToVariable(yproperty);
+			}
+		} else if(container.getComponents().get(0) instanceof VisGroup){ /*
+			VisBody child = (VisBody) container.getComponents().get(0);
+			
+			for(Mark mark:child.getComponents()) {
+				PropertyName yproperty = new PropertyName(mark.coords.y.getName());
+				if(child.constraintYProperty.get() != Constraint.None && !variable.contains(yproperty)) {
+					moveToVariable(yproperty);
+				}			
+			}*/
+		}
+	}
+	
+	public void fixXSharing() {
+		if(container.getComponents().get(0) instanceof VisCollection) {
+			VisBody child = (VisBody) container.getComponents().get(0);
+			PropertyName xproperty = new PropertyName(child.getComponents().get(0).coords.x.getName());
+			
+			if(child.constraintXProperty.get() != Constraint.None && !variable.contains(xproperty)) {
+				moveToVariable(xproperty);
+			}
+		} else if(container.getComponents().get(0) instanceof VisGroup){/*
+			VisBody child = (VisBody) container.getComponents().get(0);
+			
+			for(Mark mark:child.getComponents()) {
+				PropertyName xproperty = new PropertyName(mark.coords.x.getName());
+				if(child.constraintXProperty.get() != Constraint.None && !variable.contains(xproperty)) {
+					moveToVariable(xproperty);
+				}			
+			}
+			*/
+		}
+	}
+	
+	public void fixYConstraint(PropertyName name) {	// TODO: Do I need that???
+		if(container.getComponents().get(0) instanceof VisBody && name.isY()) {
+			VisBody child = (VisBody) container.getComponents().get(0);
+			PropertyName yproperty = new PropertyName(child.getComponents().get(0).coords.y.getName());
+
+			
+			if(child.constraintYProperty.get() == Constraint.Spacing && yproperty.equals(name)) {
+				child.constraintYProperty.set(Constraint.None);
+			}
+			
+			/*
+			if(child.constraintYProperty.get() != Constraint.None && yproperty.equals(name)) {
+				child.constraintYProperty.set(Constraint.None);
+			}*/
+		}
+	}
+	
+	public void fixXConstraint(PropertyName name) { // TODO: Do I need that???
+		if(container.getComponents().get(0) instanceof VisBody && name.isX()) {
+			VisBody child = (VisBody) container.getComponents().get(0);
+			PropertyName xproperty = new PropertyName(child.getComponents().get(0).coords.x.getName());
+			
+			
+			if(child.constraintXProperty.get() == Constraint.Spacing && xproperty.equals(name)) {
+				child.constraintXProperty.set(Constraint.None);
+			}
+			/*
+			if(child.constraintXProperty.get() != Constraint.None && xproperty.equals(name)) {
+				child.constraintXProperty.set(Constraint.None);
+			}*/
+		}
+	}
+	
+	
+	public void removeHeightSharing(ShapeMark mark) {
+		PropertyName heightPropertyName = new PropertyName(mark.height.getName());
+		if(common.contains(heightPropertyName)) moveToVariable(heightPropertyName);
+		for(Mark child:container.getComponents()) {
+			if(child instanceof VisBody)
+				((VisBody)child).getChildPropertyStructure().removeHeightSharing(mark);
+		}
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/ReferenceStructure.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/ReferenceStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..2e731e6939df64789c772603a6179986f5b1938c
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/ReferenceStructure.java
@@ -0,0 +1,18 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import fr.inria.structgraphics.types.DistributionProperty;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+
+public class ReferenceStructure {			
+	protected boolean shared = false;
+	public DistributionProperty.Constraint constraint = Constraint.None;
+	
+	public ReferenceStructure (boolean shared, Constraint constraint) {
+		this.shared = shared;
+		this.constraint = constraint;
+	}
+		
+	public boolean isShared() {
+		return shared;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/ReferenceStructureCreator.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/ReferenceStructureCreator.java
new file mode 100644
index 0000000000000000000000000000000000000000..cec6e0654dad5b0698eb5bdc0159f610d107e17c
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/ReferenceStructureCreator.java
@@ -0,0 +1,603 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.XMarkComparator;
+import fr.inria.structgraphics.graphics.YMarkComparator;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import fr.inria.structgraphics.ui.utils.Stats;
+import javafx.collections.ObservableList;
+import javafx.collections.transformation.SortedList;
+
+public class ReferenceStructureCreator {
+
+	private XReferenceStructure xReferenceStructure;
+	private YReferenceStructure yReferenceStructure;
+	
+	public ReferenceStructureCreator(ObservableList<Mark> marks, Grouping.Type gtype) {
+		
+		double valx = marks.get(0).getCoords().getX(), valy = marks.get(0).getCoords().getY();
+		
+		if(marks.size() == 1) {
+			RefX refx = marks.get(0).getCoords().getXRef();
+			RefY refy = marks.get(0).getCoords().getYRef();
+			
+			if(!(marks.get(0) instanceof VisBody)) {
+				switch(refx) {
+					case Center: 
+						valx = marks.get(0).centerX();
+						break;
+					case Left: 
+						valx = marks.get(0).left();
+						break;
+					case Right: 
+						valx = marks.get(0).right();
+						break;
+				}
+			
+				switch(refy) {
+					case Center: 
+						valy = marks.get(0).centerY();
+						break;
+					case Top: 
+						valy = marks.get(0).top();
+						break;
+					case Bottom: 
+						valy = marks.get(0).bottom();
+						break;
+				}
+			}
+				
+			xReferenceStructure = new XReferenceStructure(refx, valx, false, Constraint.None);
+			yReferenceStructure = new YReferenceStructure(refy, valy, true, Constraint.None);
+			return;
+		}
+		
+		SortedList<Mark> marksX = new SortedList<>(marks, new XMarkComparator());
+		SortedList<Mark> marksY = new SortedList<>(marks, new YMarkComparator());
+
+		/////////////////////////////////
+		List<Double> left = getXLeft(marksX);
+		Stats leftStats = new Stats(left);
+		
+		List<Double> centerx = getXCenter(marksX);
+		Stats centerXStats = new Stats(centerx);
+		
+		List<Double> right = getXRight(marksX);
+		Stats rightStats = new Stats(right);
+		
+		List<Double> bottom = getYBottom(marksY);
+		Stats bottomStats = new Stats(bottom);
+		
+		List<Double> centery = getYCenter(marksY);
+		Stats centerYStats = new Stats(centery);
+		
+		List<Double> top = getYTop(marksY);
+		Stats topStats = new Stats(top);
+
+		/////////////////////////////////
+		List<Double> gapsX = getXGap(marksX);
+		Stats gapsXStats = new Stats(gapsX);
+		
+		List<Double> gapsY = getYGap(marksY);
+		Stats gapsYStats = new Stats(gapsY);
+		/////////////////////////////////
+		
+		////////////////////////////////////
+		List<Double> topDistr = getTopDistribution(marksY);
+		Stats topDistrStats = new Stats(topDistr);
+		
+		List<Double> bottomDistr = getBottomDistribution(marksY);
+		Stats bottomDistrStats = new Stats(bottomDistr);
+		
+		List<Double> centerYDistr = getCenterYDistribution(marksY);
+		Stats centerYDistrStats = new Stats(centerYDistr);
+
+		List<Double> leftDistr = getLeftDistribution(marksX);
+		Stats leftDistrStats = new Stats(leftDistr);
+		
+		List<Double> rightDistr = getRightDistribution(marksX);
+		Stats rightDistrStats = new Stats(rightDistr);
+		
+		List<Double> centerXDistr = getCenterXDistribution(marksX);
+		Stats centerXDistrStats = new Stats(centerXDistr);
+		
+		List<Double> widthDistr = getWidths(marksX);
+		Stats widthStats = new Stats(widthDistr);
+		//////////////////////////////
+		
+		Constraint constraintX = Constraint.None, constraintY = Constraint.None;
+		RefX refx = RefX.Center;
+		RefY refy = RefY.Center;
+		boolean sharedx = false, sharedy = false;
+		valx = leftStats.min; 
+		valy = bottomStats.min;
+		
+		double dx = 0; // This is to add a gap on the x-axis based on the distribution constraint (for collections)
+		
+		if(leftStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedx = true;
+			refx = RefX.Left;
+			valx = leftStats.mean;
+		}
+		else if(centerXStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedx = true;
+			refx = RefX.Center;
+			valx = centerXStats.mean;
+		}
+		else if(rightStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedx = true;
+			refx = RefX.Right;
+			valx = rightStats.mean;
+		}
+		else if(centerXDistr.size() > 1 && centerXDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintX = Constraint.Distance;
+			refx = RefX.Center;
+			dx = centerXDistrStats.mean/8;
+		} 
+		else if(leftDistr.size() > 1 && leftDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintX = Constraint.Distance;
+			refx = RefX.Left;
+			dx = leftDistrStats.mean/8;
+		} 
+		else if(gapsX.size() > 1 && gapsXStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintX = Constraint.Spacing;
+			refx = RefX.Left;
+		}
+		else if(rightDistr.size() > 1 && rightDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintX = Constraint.Distance;
+			refx = RefX.Right;
+			dx = rightDistrStats.mean/8;
+		} 
+		
+		////////////// Y ############################
+		if(bottomStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedy = true;
+			refy = RefY.Bottom;
+			valy = bottomStats.mean;
+		}
+		else if(centerYStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedy = true;
+			refy = RefY.Center;
+			valy = centerYStats.mean;
+		}
+		else if(topStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedy = true;
+			refy = RefY.Top;
+			valy = topStats.mean;
+		}
+		else if(sharedx && (gapsY.size() == 1 || gapsYStats.var < DefaultSharingStrategy.MAX_VARIANCE)) {
+			constraintY = Constraint.Spacing;
+			refy = RefY.Bottom;
+			
+			// In this case, give priority to center x alignement
+			if(centerXDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+				refx = RefX.Center;
+				valx = centerXStats.mean;
+			}
+		} 
+		else if(sharedx && bottomDistr.size() > 1 && bottomDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintY = Constraint.Distance;
+			refy = RefY.Bottom;
+		} 
+		else if(sharedx && centerYDistr.size() > 1 && centerYDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintY = Constraint.Distance;
+			refy = RefY.Center;
+		} 
+		else if(sharedx && topDistr.size() > 1 && topDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintY = Constraint.Distance;
+			refy = RefY.Top;
+		} 
+		
+		if(gtype != Grouping.Type.Collection && sharedy && (gapsX.size() == 1 || gapsXStats.var < DefaultSharingStrategy.MAX_VARIANCE)) {
+			constraintX = Constraint.Spacing;
+			if(widthStats.var < DefaultSharingStrategy.MAX_VARIANCE) refx = RefX.Center;
+			else refx = RefX.Left;
+		}
+		
+		
+		if(gtype == Grouping.Type.Collection) valx -= dx;
+		
+		xReferenceStructure = new XReferenceStructure(refx, valx, sharedx, constraintX);
+		yReferenceStructure = new YReferenceStructure(refy, valy, sharedy, constraintY);
+	}
+	
+	/*
+	public ReferenceStructureCreator(ObservableList<Mark> marks, Grouping.Type gtype) {
+		
+		double valx = marks.get(0).getCoords().getX(), valy = marks.get(0).getCoords().getY();
+		
+		if(marks.size() == 1) {
+			RefX refx = marks.get(0).getCoords().getXRef();
+			RefY refy = marks.get(0).getCoords().getYRef();
+			
+			if(!(marks.get(0) instanceof VisBody)) {
+				switch(refx) {
+					case Center: 
+						valx = marks.get(0).centerX();
+						break;
+					case Left: 
+						valx = marks.get(0).left();
+						break;
+					case Right: 
+						valx = marks.get(0).right();
+						break;
+				}
+			
+				switch(refy) {
+					case Center: 
+						valy = marks.get(0).centerY();
+						break;
+					case Top: 
+						valy = marks.get(0).top();
+						break;
+					case Bottom: 
+						valy = marks.get(0).bottom();
+						break;
+				}
+			}
+				
+			xReferenceStructure = new XReferenceStructure(refx, valx, false, Constraint.None);
+			yReferenceStructure = new YReferenceStructure(refy, valy, true, Constraint.None);
+			return;
+		}
+		
+		SortedList<Mark> marksX = new SortedList<>(marks, new XMarkComparator());
+		SortedList<Mark> marksY = new SortedList<>(marks, new YMarkComparator());
+
+		/////////////////////////////////
+		List<Double> left = getXLeft(marksX);
+		Stats leftStats = new Stats(left);
+		
+		List<Double> centerx = getXCenter(marksX);
+		Stats centerXStats = new Stats(centerx);
+		
+		List<Double> right = getXRight(marksX);
+		Stats rightStats = new Stats(right);
+		
+		List<Double> bottom = getYBottom(marksY);
+		Stats bottomStats = new Stats(bottom);
+		
+		List<Double> centery = getYCenter(marksY);
+		Stats centerYStats = new Stats(centery);
+		
+		List<Double> top = getYTop(marksY);
+		Stats topStats = new Stats(top);
+
+		/////////////////////////////////
+		List<Double> gapsX = getXGap(marksX);
+		Stats gapsXStats = new Stats(gapsX);
+		
+		List<Double> gapsY = getYGap(marksY);
+		Stats gapsYStats = new Stats(gapsY);
+		/////////////////////////////////
+		
+		////////////////////////////////////
+		List<Double> topDistr = getTopDistribution(marksY);
+		Stats topDistrStats = new Stats(topDistr);
+		
+		List<Double> bottomDistr = getBottomDistribution(marksY);
+		Stats bottomDistrStats = new Stats(bottomDistr);
+		
+		List<Double> centerYDistr = getCenterYDistribution(marksY);
+		Stats centerYDistrStats = new Stats(centerYDistr);
+
+		List<Double> leftDistr = getLeftDistribution(marksX);
+		Stats leftDistrStats = new Stats(leftDistr);
+		
+		List<Double> rightDistr = getRightDistribution(marksX);
+		Stats rightDistrStats = new Stats(rightDistr);
+		
+		List<Double> centerXDistr = getCenterXDistribution(marksX);
+		Stats centerXDistrStats = new Stats(centerXDistr);
+		
+		List<Double> widthDistr = getWidths(marksX);
+		Stats widthStats = new Stats(widthDistr);
+		//////////////////////////////
+		
+		Constraint constraintX = Constraint.None, constraintY = Constraint.None;
+		RefX refx = RefX.Center;
+		RefY refy = RefY.Center;
+		boolean sharedx = false, sharedy = false;
+		valx = leftStats.min; 
+		valy = bottomStats.min;
+		
+		double dx = 0; // This is to add a gap on the x-axis based on the distribution constraint (for collections)
+		
+		if(leftStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedx = true;
+			refx = RefX.Left;
+			valx = leftStats.mean;
+		}
+		else if(centerXStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedx = true;
+			refx = RefX.Center;
+			valx = centerXStats.mean;
+		}
+		else if(rightStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedx = true;
+			refx = RefX.Right;
+			valx = rightStats.mean;
+		}
+		else if(centerXDistr.size() > 1 && centerXDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintX = Constraint.Distance;
+			refx = RefX.Center;
+			dx = centerXDistrStats.mean/8;
+		} 
+		else if(leftDistr.size() > 1 && leftDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintX = Constraint.Distance;
+			refx = RefX.Left;
+			dx = leftDistrStats.mean/8;
+		} 
+		else if(gapsX.size() > 1 && gapsXStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintX = Constraint.Spacing;
+			refx = RefX.Left;
+		}
+		else if(rightDistr.size() > 1 && rightDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintX = Constraint.Distance;
+			refx = RefX.Right;
+			dx = rightDistrStats.mean/8;
+		} 
+		
+		////////////// Y ############################
+		if(bottomStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedy = true;
+			refy = RefY.Bottom;
+			valy = bottomStats.mean;
+		}
+		else if(centerYStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedy = true;
+			refy = RefY.Center;
+			valy = centerYStats.mean;
+		}
+		else if(topStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			sharedy = true;
+			refy = RefY.Top;
+			valy = topStats.mean;
+		}
+		else if(sharedx && (gapsY.size() == 1 || gapsYStats.var < DefaultSharingStrategy.MAX_VARIANCE)) {
+			constraintY = Constraint.Spacing;
+			refy = RefY.Bottom;
+			
+			// In this case, give priority to center x alignement
+			if(centerXDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+				refx = RefX.Center;
+				valx = centerXStats.mean;
+			}
+		} 
+		else if(sharedx && bottomDistr.size() > 1 && bottomDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintY = Constraint.Distance;
+			refy = RefY.Bottom;
+		} 
+		else if(sharedx && centerYDistr.size() > 1 && centerYDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintY = Constraint.Distance;
+			refy = RefY.Center;
+		} 
+		else if(sharedx && topDistr.size() > 1 && topDistrStats.var < DefaultSharingStrategy.MAX_VARIANCE) {
+			constraintY = Constraint.Distance;
+			refy = RefY.Top;
+		} 
+		
+		if(gtype != Grouping.Type.Collection && sharedy && (gapsX.size() == 1 || gapsXStats.var < DefaultSharingStrategy.MAX_VARIANCE)) {
+			constraintX = Constraint.Spacing;
+			if(widthStats.var < DefaultSharingStrategy.MAX_VARIANCE) refx = RefX.Center;
+			else refx = RefX.Left;
+		}
+		
+		
+		if(gtype == Grouping.Type.Collection) valx -= dx;
+		
+		xReferenceStructure = new XReferenceStructure(refx, valx, sharedx, constraintX);
+		yReferenceStructure = new YReferenceStructure(refy, valy, sharedy, constraintY);
+	}
+	*/
+	
+	public XReferenceStructure getXReferenceStructure() {
+		return xReferenceStructure;
+	}
+	
+	public YReferenceStructure getYReferenceStructure() {
+		return yReferenceStructure;
+	}
+	
+	protected List<Double> getXLeft(List<Mark> marks){
+		List<Double> left = new ArrayList<>();		
+		for(Mark mark: marks) {
+			if(mark instanceof VisBody) left.add(mark.getCoords().getX());
+			else left.add(mark.left());
+		}
+		return left;
+	}
+	
+	protected List<Double> getXRight(List<Mark> marks){
+		List<Double> right = new ArrayList<>();		
+		for(Mark mark: marks) {
+			if(mark instanceof VisBody) right.add(mark.getCoords().getX());
+			else right.add(mark.right());
+		}
+		return right;
+	}
+
+	protected List<Double> getXCenter(List<Mark> marks){
+		List<Double> center = new ArrayList<>();		
+		for(Mark mark: marks) {
+			if(mark instanceof VisBody) center.add(mark.getCoords().getX());
+			else center.add(mark.centerX());
+		}
+		return center;
+	}
+	
+	protected List<Double> getYTop(List<Mark> marks){
+		List<Double> top = new ArrayList<>();		
+		for(Mark mark: marks) {
+			if(mark instanceof VisBody) top.add(mark.getCoords().getY());
+			else top.add(mark.top());
+		}
+		return top;
+	}
+	
+	protected List<Double> getYCenter(List<Mark> marks){
+		List<Double> center = new ArrayList<>();		
+		for(Mark mark: marks) {
+			if(mark instanceof VisBody) center.add(mark.getCoords().getY());
+			else center.add(mark.centerY());
+		}
+		return center;
+	}
+	
+	protected List<Double> getYBottom(List<Mark> marks){
+		List<Double> bottom = new ArrayList<>();		
+		for(Mark mark: marks) {
+			if(mark instanceof VisBody) bottom.add(mark.getCoords().getY());
+			else bottom.add(mark.bottom());
+		}
+		return bottom ;
+	}
+	
+	
+	protected List<Double> getLeftDistribution(SortedList<Mark> marks){
+		List<Double> dist = new ArrayList<>();	
+		if(marks.size() < 2) return dist;
+		
+		if(marks.get(0) instanceof VisBody) {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).getCoords().getX() - marks.get(i-1).getCoords().getX());
+			}
+		} else {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).left() - marks.get(i-1).left());
+			}
+		}
+				
+		return dist;
+	}
+	
+	protected List<Double> getCenterXDistribution(SortedList<Mark> marks){
+		List<Double> dist = new ArrayList<>();	
+		if(marks.size() < 2) return dist;
+		
+		if(marks.get(0) instanceof VisBody) {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).getCoords().getX() - marks.get(i-1).getCoords().getX());
+			}
+		} else {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).centerX() - marks.get(i-1).centerX());
+			}
+		}
+		
+		return dist;
+	}
+	
+	protected List<Double> getRightDistribution(SortedList<Mark> marks){
+		List<Double> dist = new ArrayList<>();	
+		if(marks.size() < 2) return dist;
+		
+		if(marks.get(0) instanceof VisBody) {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).getCoords().getX() - marks.get(i-1).getCoords().getX());
+			}
+		} else {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).right() - marks.get(i-1).right());
+			}
+		}
+		
+		return dist;
+	}
+	
+	protected List<Double> getBottomDistribution(SortedList<Mark> marks){
+		List<Double> dist = new ArrayList<>();	
+		if(marks.size() < 2) return dist;
+		
+		if(marks.get(0) instanceof VisBody) {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).getCoords().getY() - marks.get(i-1).getCoords().getY());
+			}
+		} else {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).bottom() - marks.get(i-1).bottom());
+			}
+		}
+		
+		return dist;
+	}
+	
+	protected List<Double> getCenterYDistribution(SortedList<Mark> marks){
+		List<Double> dist = new ArrayList<>();	
+		if(marks.size() < 2) return dist;
+		
+		if(marks.get(0) instanceof VisBody) {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).getCoords().getY() - marks.get(i-1).getCoords().getY());
+			}
+		} else {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).centerY() - marks.get(i-1).centerY());
+			}
+		}
+		
+		return dist;
+	}
+	
+	protected List<Double> getTopDistribution(SortedList<Mark> marks){
+		List<Double> dist = new ArrayList<>();	
+		if(marks.size() < 2) return dist;
+		
+		if(marks.get(0) instanceof VisBody) {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).getCoords().getY() - marks.get(i-1).getCoords().getY());
+			}
+		} else {
+			for(int i = 1; i < marks.size(); ++i) {
+				dist.add(marks.get(i).top() - marks.get(i-1).top());
+			}
+		}
+		
+		return dist;
+	}
+	
+	protected List<Double> getXGap(SortedList<Mark> marks){
+		List<Double> gap = new ArrayList<>();	
+		if(marks.size() < 2) return gap;
+		
+		for(int i = 1; i < marks.size(); ++i) {
+			double right = marks.get(i-1).right();
+			double left = marks.get(i).left();
+			gap.add(left - right);
+		}
+		
+		return gap;
+	}
+	
+	protected List<Double> getYGap(SortedList<Mark> marks){		
+		List<Double> gap = new ArrayList<>();	
+		if(marks.size() < 2) return gap;
+		
+		for(int i = 1; i < marks.size(); ++i) {
+			double top = marks.get(i-1).top();
+			double bottom = marks.get(i).bottom();
+			gap.add(bottom - top);
+		}
+		
+		return gap;
+	}
+	
+	protected List<Double> getWidths(SortedList<Mark> marks){
+		List<Double> ws = new ArrayList<>();	
+		if(marks.size() < 2) return ws;
+		
+		for(int i = 1; i < marks.size(); ++i) {
+			double width = marks.get(i-1).width();
+			ws.add(width);
+		}
+		
+		return ws;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/SharingStrategy.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/SharingStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf194ee612c0a3308cdf055977981602b3beeb0c
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/SharingStrategy.java
@@ -0,0 +1,34 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeMap;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.utils.GroupBinding;
+import javafx.collections.ObservableList;
+
+
+public abstract class SharingStrategy {
+	
+	public void share(Collection<FlexibleListProperty> properties, SortedSet<PropertyName> common, SortedSet<PropertyName> variable) {
+		for(FlexibleListProperty column: properties) {
+			if(isVariable(column)) {
+				variable.add(new PropertyName(column.getName()));
+			}
+			else common.add(new PropertyName(column.getName()));
+		}
+	}
+	
+	protected abstract boolean isVariable(FlexibleListProperty column);	
+	public abstract VisCollection createCollection(ObservableList<Mark> marks);
+	public abstract VisGroup createGroup(ObservableList<Mark> marks);
+	public abstract void share(Map<PropertyName, FlexibleListProperty> properties, TreeMap<PropertyName, ArrayList<GroupBinding>> bindings, 
+			SortedSet<PropertyName> common, SortedSet<PropertyName> variable);
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/XReferenceStructure.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/XReferenceStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..7606f3fa6c241f97b4e551150958378c88aa3825
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/XReferenceStructure.java
@@ -0,0 +1,28 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefX;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+
+public class XReferenceStructure extends ReferenceStructure {			
+	private RefX refx = null;
+	private double x;
+
+	public XReferenceStructure (RefX refx, double x, boolean shared, Constraint constraint) {
+		super(shared, constraint);
+		this.refx = refx;
+		this.x = x;				
+	}
+	
+	public RefX getRef() {
+		return refx;
+	}
+	
+	public double getRefValue() {
+		return x;
+	}
+	
+	public String toString() {
+		return "X: " + refx + ", " + x + " " + constraint;
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupings/YReferenceStructure.java b/src/fr/inria/structgraphics/ui/viscanvas/groupings/YReferenceStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b22fbbd903e5435d08952ffce8f3c7dea658a63
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupings/YReferenceStructure.java
@@ -0,0 +1,28 @@
+package fr.inria.structgraphics.ui.viscanvas.groupings;
+
+import fr.inria.structgraphics.graphics.ReferenceCoords.RefY;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+
+public class YReferenceStructure extends ReferenceStructure {			
+	private RefY refy;
+	private double y;
+	
+	public YReferenceStructure (RefY refy, double y, boolean shared, Constraint constraint) {
+		super(shared, constraint);
+		this.refy = refy;	
+		this.y = y;		
+	}
+	
+	public RefY getRef() {
+		return refy;
+	}
+	
+	public double getRefValue() {
+		return y;
+	}
+	
+	public String toString() {
+		return "Y: " + refy + ", " + y + " " + constraint;
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/Axis.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/Axis.java
new file mode 100644
index 0000000000000000000000000000000000000000..13c0ca7b7adc1605d701ab4fc1aa0a037c974ef8
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/Axis.java
@@ -0,0 +1,131 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.types.PropertyName;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import fr.inria.structgraphics.ui.spreadsheet.MathTransformation;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.Group;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Line;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.scene.text.Text;
+
+public abstract class Axis extends Group implements ChangeListener<String>/*implements InvalidationListener*/ {
+
+	protected Font textFont = new Font(10);
+	protected Font labelFont = Font.font("Verdana", FontWeight.BOLD, 11);
+	//protected Color stroke = Color.GREY;
+	//protected Color textColor = Color.GREY;
+	protected double axisStrokeWidth = 0.8;
+	protected double tickStrokeWidth = 0.6;
+	protected double ticLength = 6;
+	protected double labelGap = 1;
+	
+	protected VisCollection group;
+	protected DataVariable variable;
+	
+	protected Line axisLine;
+	protected Group tics;
+	protected Group values;
+	protected Text label;
+	
+	protected double min, max;
+	protected double minValue, maxValue;
+	
+	public Axis(VisCollection group) {
+		this.group = group;
+		setVisible(false);
+				
+		axisLine = new Line();
+		tics = new Group();
+		values = new Group();
+		label = new Text();
+		label.setFont(labelFont);
+		
+		label.fillProperty().bind(((VisFrame)group.getRoot()).stroke);
+		axisLine.strokeProperty().bind(((VisFrame)group.getRoot()).stroke);// setStroke(stroke);
+		axisLine.setStrokeWidth(axisStrokeWidth);
+		
+		getChildren().add(axisLine);
+		getChildren().add(tics);
+		getChildren().add(values);
+		getChildren().add(label);
+	}
+	
+	public void createCopy(Axis axis) {		
+		axis.variable = variable;
+		axis.setVisible(isVisible());
+		axis.update();		
+	}
+	
+	public void showVariable(DataVariable variable) {
+		if(variable != this.variable && this.variable != null) {
+			this.variable.scaleShownProperty.set(false);
+			this.variable.transformationProperty().get().getExpression().removeListener(this);
+		}
+		this.variable = variable;
+		
+		if(!variable.scaleShownProperty.get()) {
+			setVisible(true);
+			update();
+		}
+		else setVisible(false);
+		
+		variable.transformationProperty().get().getExpression().addListener(this);
+	}
+	
+	public void showVariableOnParent(DataVariable variable) {
+		if(variable != this.variable && this.variable != null) {
+			this.variable.scaleShownPropertyOuter.set(false);
+			this.variable.transformationProperty().get().getExpression().removeListener(this);
+		}
+		this.variable = variable;
+		
+		if(!variable.scaleShownPropertyOuter.get()) {
+			setVisible(true);
+			update();
+		}
+		else setVisible(false);
+		
+		variable.transformationProperty().get().getExpression().addListener(this);
+	}
+	
+	@Override
+	public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
+		update();
+	}
+	
+	protected double transform(Object val) {
+		return ((MathTransformation)variable.transformationProperty().get()).transform(val);
+	}
+	
+	protected double invTransform(double val) {
+		return ((MathTransformation)variable.transformationProperty().get()).inverseTransform(val);
+	}
+/*
+	@Override
+	public void invalidated(Observable observable) {
+		update();
+	}
+*/	
+	public void update() { 
+		if(!isVisible()) return; 
+		updateTicksAndValues();
+		updateLine();
+		updateLabel();
+	}
+	
+		
+	protected FlexibleListProperty getValues() {
+		return group.getChildPropertyStructure().getProperty(new PropertyName(variable.getPropertyName())).flattenFlex();
+	}
+	
+	protected abstract void updateLine();
+	protected abstract void updateTicksAndValues();
+	protected abstract void updateLabel();
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/AxisX.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/AxisX.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4b46ca837f1171b9b3f15fc21749330fcebe571
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/AxisX.java
@@ -0,0 +1,168 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeMap;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.ui.spreadsheet.DataTransformation;
+import fr.inria.structgraphics.ui.spreadsheet.DiscreteTransformation;
+import fr.inria.structgraphics.ui.spreadsheet.MappingProperty;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable.DataType;
+import fr.inria.structgraphics.ui.utils.Ticker;
+import javafx.beans.property.Property;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.shape.Line;
+import javafx.scene.text.Text;
+
+public class AxisX extends Axis {
+		
+	private double offset = 0; 
+	
+	public AxisX(VisCollection group) {
+		super(group);
+	}
+	
+	@Override
+	protected void updateLine() {
+		axisLine.startYProperty().set(group.getInteractor().getXAxis().startYProperty().get());
+		axisLine.endYProperty().set(group.getInteractor().getXAxis().endYProperty().get());
+		axisLine.startXProperty().set(min);
+		axisLine.endXProperty().set(max);
+	}
+	
+	@Override
+	protected void updateTicksAndValues() {
+		values.getChildren().clear();
+		tics.getChildren().clear();
+		offset = 0;
+		
+		List<Double> positions, values = null;
+		double endY = axisLine.getStartY() + ticLength;
+		
+		if(variable.getType().equals(DataType.Functional)) {
+			minValue = 0;
+			maxValue = 0;
+			
+			if(variable.isX()) { // This is to show the axis only along the active y values
+				FlexibleListProperty propValues = getValues();
+				for(Property prop: propValues) {
+					if((double)prop.getValue() < minValue) minValue = (double)prop.getValue();
+					if((double)prop.getValue() > maxValue) maxValue = (double)prop.getValue();
+				}
+			} else {
+				minValue = group.getInteractor().left.get();
+				maxValue = group.getInteractor().right.get();
+			}
+			
+			
+			double min = transform(minValue);
+			double max = transform(maxValue);
+			
+			//double min = transform(group.getInteractor().left.get());
+			//double max = transform(group.getInteractor().right.get());
+				
+			Ticker ticker = new Ticker(min, max, 10, transform(new Double(20)) - transform(new Double(0)));
+			positions = ticker.getTicks();
+			
+			for(int i = 0; i < positions.size(); ++i) {
+				double val = positions.get(i); 
+				double x = invTransform(val);
+				
+				if(i == 0) this.min = x;
+				else if(i == positions.size() - 1) this.max = x;
+				
+				Line line = new Line(x, axisLine.getStartY(), x, endY);				
+				line.strokeProperty().bind(((VisFrame)group.getRoot()).stroke);// setStroke(stroke);
+				
+				//line.setStroke(stroke);
+				line.setStrokeWidth(tickStrokeWidth);
+				tics.getChildren().add(line);
+				
+				if(values != null) updateValue(x, line.getEndY(), values.get(i));
+				else updateValue(x, line.getEndY(), x);
+			}
+			
+		} else {
+			minValue = group.getInteractor().left.get();
+			maxValue = group.getInteractor().right.get();
+			
+			this.min = group.getInteractor().getXAxis().startXProperty().get();
+			this.max = group.getInteractor().getXAxis().endXProperty().get();
+			
+			positions = new ArrayList<>();
+			values = new ArrayList<>();
+			
+			DiscreteTransformation transformation = (DiscreteTransformation)variable.transformationProperty().get();
+			TreeMap<MappingProperty, StringProperty> map = transformation.getMap();
+			for(MappingProperty prop:map.keySet()) {
+				double dx = 0;
+				values.add((double)prop.get());
+				positions.add((double)prop.get() + dx);
+			}
+			
+			/*
+			List<Mark> marks = group.getComponents();
+			for(Mark mark : marks) {
+				double dx = 0;
+				values.add(mark.getCoords().x.get());
+				positions.add(mark.getCoords().x.get() + dx);
+			}*/
+			
+			for(int i = 0; i < positions.size(); ++i) {
+				double x = positions.get(i); 
+				Line line = new Line(x, axisLine.getStartY(), x, endY);
+				line.strokeProperty().bind(((VisFrame)group.getRoot()).stroke);// setStroke(stroke);
+//				line.setStroke(stroke);
+				line.setStrokeWidth(tickStrokeWidth);
+				tics.getChildren().add(line);
+				
+				if(values != null) updateValue(x, line.getEndY(), values.get(i));
+				else updateValue(x, line.getEndY(), x);
+			}
+		}
+			
+
+	}
+	
+	protected void updateValue(double posx, double posy, double xvalue) {		
+		double dy = 0;
+		if(variable.getType().equals(DataType.Symbolic)) {
+			dy = group.coords.getY() - group.bottom();
+		}
+		
+		String value = variable.transformationProperty().get().toData(xvalue);
+		
+		Text label = new Text(value);
+		label.setFont(textFont);
+		//label.setFill(textColor);
+		label.fillProperty().bind(((VisFrame)group.getRoot()).stroke);// setStroke(stroke);
+		
+		label.xProperty().set(posx - label.getLayoutBounds().getWidth()/2);
+		
+		label.yProperty().set(posy + label.getLayoutBounds().getHeight() + labelGap + dy);
+		offset = Math.max(offset, label.yProperty().get());
+		
+		values.getChildren().add(label);
+	}
+	
+	@Override
+	protected void updateLabel() {		
+		label.textProperty().unbind();
+		label.textProperty().bind(variable.getName(0));
+		
+		//double min = group.getInteractor().left.get();
+		//double max = group.getInteractor().right.get();
+		double centerx = (maxValue + minValue)/2;
+
+		label.xProperty().set(centerx - label.getLayoutBounds().getWidth()/2);
+		label.yProperty().set(offset + label.getLayoutBounds().getHeight() + labelGap);		
+	}
+
+
+}
+
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/AxisY.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/AxisY.java
new file mode 100644
index 0000000000000000000000000000000000000000..5bb34f55c7880624b94e0cba98c63e075cbe1b73
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/AxisY.java
@@ -0,0 +1,162 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.types.FlexibleListProperty;
+import fr.inria.structgraphics.ui.spreadsheet.MathTransformation;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable.DataType;
+import fr.inria.structgraphics.ui.utils.Ticker;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.Property;
+import javafx.scene.shape.Line;
+import javafx.scene.text.Text;
+import javafx.scene.transform.Rotate;
+
+public class AxisY extends Axis {
+	
+	private double offset = 0;
+	
+	public AxisY(VisCollection group) {
+		super(group);
+		
+		Rotate rotation = new Rotate();
+		rotation.pivotXProperty().set(0);
+		rotation.pivotYProperty().set(0);
+		rotation.setAngle(-90);
+		label.getTransforms().add(rotation);
+	}
+
+	@Override
+	protected void updateLine() {
+		axisLine.startYProperty().set(min);
+		axisLine.endYProperty().set(max);
+		
+		axisLine.startXProperty().set(group.getInteractor().getYAxis().startXProperty().get());
+		axisLine.endXProperty().set(group.getInteractor().getYAxis().endXProperty().get());
+	}
+	
+	@Override
+	protected void updateTicksAndValues() {
+		values.getChildren().clear();
+		tics.getChildren().clear();
+		offset = 0;
+		
+		List<Double> positions, values = null;
+		double endX = axisLine.getStartX() - ticLength;
+		
+		if(variable.getType().equals(DataType.Functional)) {
+			minValue = 0;
+			maxValue = 0;
+			
+			if(variable.isY()) { // This is to show the axis only along the active y values
+				FlexibleListProperty propValues = getValues();
+				for(Property prop: propValues) {
+					if((double)prop.getValue() < minValue) minValue = (double)prop.getValue();
+					if((double)prop.getValue() > maxValue) maxValue = (double)prop.getValue();
+				}
+			} else {
+				minValue = -group.getInteractor().bottom.get();
+				maxValue = -group.getInteractor().top.get();
+			}
+			
+			double min = transform(minValue);
+			double max = transform(maxValue);
+		
+			//double min = transform(-group.getInteractor().bottom.get());
+			//double max = transform(-group.getInteractor().top.get());
+				
+			Ticker ticker = new Ticker(min, max, 10, transform(new Double(15)) - transform(new Double(0)));
+			positions = ticker.getTicks();
+			
+			for(int i = 0; i < positions.size(); ++i) { 
+				double val = positions.get(i); 
+				double y = invTransform(val);
+				
+				if(i == 0) this.min = -y;
+				else if(i == positions.size() - 1) this.max = -y;
+				
+				Line line = new Line(axisLine.getStartX(), -y, endX, -y);
+				line.strokeProperty().bind(((VisFrame)group.getRoot()).stroke);
+				//line.setStroke(stroke);
+				line.setStrokeWidth(tickStrokeWidth);
+				tics.getChildren().add(line);
+				
+				if(values != null) updateValue(-y, line.getEndX(), -values.get(i));
+				else updateValue(-y, line.getEndX(), -y);
+			}
+		} else {
+			minValue = -group.getInteractor().bottom.get();
+			maxValue = -group.getInteractor().top.get();
+			
+			this.min = group.getInteractor().getYAxis().startYProperty().get();
+			this.max = group.getInteractor().getYAxis().endYProperty().get();
+			
+			positions = new ArrayList<>();
+			values = new ArrayList<>();
+			List<Mark> marks = group.getComponents();
+			for(Mark mark : marks) {
+				double dy = 0;
+				values.add(mark.getCoords().y.get());
+				positions.add(mark.getCoords().y.get() + dy);
+			}
+			
+			for(int i = 0; i < positions.size(); ++i) {
+				double y = positions.get(i); 
+				Line line = new Line(axisLine.getStartX(), -y, endX, -y);
+				line.strokeProperty().bind(((VisFrame)group.getRoot()).stroke);
+				//line.setStroke(stroke);
+				line.setStrokeWidth(tickStrokeWidth);
+				tics.getChildren().add(line);
+				
+				if(values != null) updateValue(-y, line.getEndX(), -values.get(i));
+				else updateValue(-y, line.getEndX(), -y);
+			}
+		}
+	}
+
+
+	/*
+	protected double getInverseTransformed(double val) {
+		return new Double(variable.transformationProperty().get().toData(val));
+	}*/
+
+	protected void updateValue(double posy, double posx, double yvalue) {
+			String value = variable.transformationProperty().get().toData(yvalue == 0? 0 : -yvalue);
+			
+			Text label = new Text(value);
+			label.setFont(textFont);
+//			label.setFill(textColor);
+			label.fillProperty().bind(((VisFrame)group.getRoot()).stroke);
+			
+			label.yProperty().set(posy + label.getLayoutBounds().getHeight()/4);
+			label.xProperty().set(posx - label.getLayoutBounds().getWidth() - labelGap);
+			offset = Math.min(offset, label.xProperty().get());
+			
+			values.getChildren().add(label);
+	}
+	
+	
+	InvalidationListener labelListener = new InvalidationListener() {
+		@Override
+		public void invalidated(Observable observable) {
+			
+		}
+	};
+	
+	
+	@Override
+	protected void updateLabel() {
+		label.textProperty().bind(variable.getName(0));	
+		
+		double centery = -(maxValue + minValue)/2;
+		
+		label.xProperty().set(-centery - label.getLayoutBounds().getWidth()/2);
+		label.yProperty().set(offset - label.getLayoutBounds().getHeight() - labelGap);	
+	}
+
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/BodyInteractor.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/BodyInteractor.java
new file mode 100644
index 0000000000000000000000000000000000000000..76459f70a05fcfbca21dca00fe888b76144765be
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/BodyInteractor.java
@@ -0,0 +1,88 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import fr.inria.structgraphics.graphics.ComplexShape;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.ui.utils.Cloner;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.scene.Group;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Shape;
+
+public abstract class BodyInteractor extends ComplexShape {
+	
+	protected final static Color COL = new Color(Color.DEEPPINK.getRed(), Color.DEEPPINK.getGreen(), Color.DEEPPINK.getBlue(), 0.6);// Color.DEEPPINK;
+	protected final static Color COL2 = new Color(Color.CORNFLOWERBLUE.getRed(), Color.CORNFLOWERBLUE.getGreen(), Color.CORNFLOWERBLUE.getBlue(), 0.6);// Color.DEEPPINK;
+
+	protected final static Color COL3 = new Color(Color.GOLDENROD.getRed(), Color.GOLDENROD.getGreen(), Color.GOLDENROD.getBlue(), 0.6);
+	
+	protected Circle handler;
+	public DoubleProperty left = new SimpleDoubleProperty(), right = new SimpleDoubleProperty(100), top = new SimpleDoubleProperty(-100), bottom = new SimpleDoubleProperty();
+	
+	protected VisBody group;
+	
+	public BodyInteractor(VisBody group) {		
+		this.group = group;
+		drawHandler();
+		drawBoundary();
+	}
+	
+	protected void drawHandler() {
+		handler = new Circle(0, 0, group.isExternal() ? 10 : 6);
+		
+		getChildren().add(handler);
+		handler.setFill(new Color(1, 1, 1, 0.1));
+		handler.setStroke(group.isExternal() ? COL : COL2);
+		
+		addToGhost(Cloner.clone(handler));
+	}
+	
+	protected abstract void drawBoundary();
+	
+	public boolean contains(Circle trace) {		
+		return handler.contains(trace.getCenterX(), trace.getCenterY());
+	}
+	
+	public boolean intersectsCenter(Shape trace) {
+		if(trace == null || !handler.isVisible()) return false;
+		
+		Shape intersection = Shape.intersect((Shape) handler, trace);			
+		if(!(intersection instanceof Path) || !((Path)intersection).getElements().isEmpty()) return true;
+		
+		return false;
+	}
+	
+	@Override
+	public boolean intersects(Shape trace) { 
+		if(handler.isVisible()) return super.intersects(trace);
+		else return false;
+	}
+
+	public void redraw() {
+		clear();
+		drawHandler();
+		drawBoundary();
+		refresh();
+	}
+
+	public void refresh() {		
+		ghost.getChildren().clear();
+		addToGhost(Cloner.clone(handler));
+	}
+	
+
+	public double getXStart() {
+		return handler.getCenterX();
+	}
+	
+	public double getYStart() {
+		return handler.getCenterY();
+	}
+	
+	public abstract Group createCopy(double dx, double dy);
+
+	public abstract double getWidth();
+	public abstract double getHeight();
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/CollectionInteractor.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/CollectionInteractor.java
new file mode 100644
index 0000000000000000000000000000000000000000..736d84325c01d991aac51656b5cacfba3b6ff5d4
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/CollectionInteractor.java
@@ -0,0 +1,119 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.types.AlignmentProperty;
+import fr.inria.structgraphics.types.AlignmentXProperty;
+import fr.inria.structgraphics.ui.utils.Cloner;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Shape;
+
+public class CollectionInteractor extends BodyInteractor {
+
+	private Line xAxis, yAxis;
+		
+	public CollectionInteractor(VisCollection collection) {
+		super(collection);
+	}
+	
+	protected boolean isXNeeded() {
+		if(group.isExternal()) return true;
+		else {
+			Container container = group.getContainer();
+			if(container instanceof VisCollection && ((VisCollection)container).getAlignYProperty().get() == AlignmentProperty.XSticky.Yes)
+				return false;
+			
+			return true;
+		}
+	}
+	
+	protected boolean isYNeeded() {
+		if(group.isExternal()) return true;
+		else {
+			Container container = group.getContainer();
+			if(container instanceof VisCollection && ((VisCollection)container).getAlignXProperty().get() == AlignmentProperty.YSticky.Yes)
+				return false;
+			
+			return true;
+		}
+	}
+	
+	@Override
+	protected void drawBoundary() {
+		xAxis = new Line(0, 0, 100, 0);
+		xAxis.startXProperty().bind(left);
+		xAxis.endXProperty().bind(right);	
+		getChildren().add(xAxis);
+		xAxis.setStroke(group.isExternal() ? COL : COL2);
+		if(!group.isExternal()) xAxis.getStrokeDashArray().addAll(2d);
+		else xAxis.getStrokeDashArray().clear();
+		
+		yAxis = new Line(0, 0, 0, -100);
+		yAxis.startYProperty().bind(bottom);
+		yAxis.endYProperty().bind(top);
+		getChildren().add(yAxis);
+		yAxis.setStroke(group.isExternal() ? COL : COL2);
+		if(!group.isExternal()) yAxis.getStrokeDashArray().addAll(2d);
+		else yAxis.getStrokeDashArray().clear();
+		
+		addToGhost(Cloner.clone(xAxis));
+		addToGhost(Cloner.clone(yAxis));
+	}
+	
+	public Line getXAxis() {
+		return xAxis;
+	}
+	
+	public Line getYAxis() {
+		return yAxis;
+	}
+	
+	@Override
+	public void refresh() {		
+		super.refresh();
+		addToGhost(Cloner.clone(xAxis));
+		addToGhost(Cloner.clone(yAxis));
+		
+		boolean isX = isXNeeded();
+		boolean isY = isYNeeded();
+		
+		xAxis.setVisible(isX);
+		yAxis.setVisible(isY);
+		handler.setVisible(isX || isY);
+	}
+	
+	@Override
+	public void setHighlight(boolean highlight) { 
+		super.setHighlight(highlight && handler.isVisible());
+	}
+	
+	@Override
+	public Group createCopy(double dx, double dy) { 
+		Group group = new Group();
+		Circle handler_ = new Circle(dx, dy, 10);
+		Line xAxis_ = new Line(xAxis.getStartX() + dx, xAxis.getStartY() + dy, xAxis.getEndX() + dx, xAxis.getEndY() + dy);
+		Line yAxis_ = new Line(yAxis.getStartX() + dx, yAxis.getStartY() + dy, yAxis.getEndX() + dx, yAxis.getEndY() + dy);
+			
+		group.getChildren().add(handler_);
+		group.getChildren().add(xAxis_);
+		group.getChildren().add(yAxis_);
+		
+		return group;
+	}
+
+	@Override
+	public double getWidth() {
+		return Math.abs(xAxis.getEndX() - xAxis.getStartX());
+	}
+	
+	@Override
+	public double getHeight() {
+		return Math.abs(yAxis.getEndY() - yAxis.getStartY());
+	}
+}
+
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/ConstraintController.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/ConstraintController.java
new file mode 100644
index 0000000000000000000000000000000000000000..b201ed04ad9731290d4c1cd7b8fa3522421e6bf2
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/ConstraintController.java
@@ -0,0 +1,76 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.DistributionProperty;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Shape;
+
+public abstract class ConstraintController extends Group {
+	
+	public enum ConstraintHandle {
+		LEFT, RIGHT, UP, DOWN
+	}
+	
+	protected DistributionProperty.Constraint type = Constraint.None;
+	protected VisBody group;
+	
+	protected double distance_init;
+	protected Mark activeMark = null;
+	
+	protected static boolean handlerhold = false; // A constraint handler is currently hold/dragged
+	protected static int xselectionIndex  = 0, yselectionIndex = 0;
+	protected static double xselectionPos = Double.MAX_VALUE, yselectionPos = Double.MAX_VALUE;
+	
+	protected static VisBody highlighted_group = null;
+	
+	public ConstraintController(VisBody group) {
+		this.group = group;
+	}
+
+	public abstract void updateMarkPositions(Mark mark);
+	public abstract void setMark(Mark mark, boolean highlight);
+
+	
+	public ConstraintController getSelf() {
+		return this;
+	}
+	
+	public boolean intersects(Circle trace) {
+		if(!isVisible()) return false;
+		
+		if(trace == null) return false;
+		
+		for(Node shape: getChildren()) {
+			if(shape instanceof Circle && shape.isVisible()) {
+				Shape intersection = Shape.intersect((Circle) shape, trace);			
+				if(!(intersection instanceof Path) || !((Path)intersection).getElements().isEmpty()) {
+					
+					selectHandle((Circle)shape);
+					
+					return true;
+				}
+			}
+		}	
+		return false;
+	}
+
+	protected void selectHandle(Circle shape) {
+		ConstraintController.handlerhold = true;
+	}
+	
+	public void unselectHandle() {
+		if(activeMark != null) activeMark.setConstraintControl(null, null);
+		ConstraintController.handlerhold = false;
+	}
+
+	
+	public abstract void refresh();
+
+	public abstract void translate(Line lineTrace, ConstraintHandle constraintHandler);
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/ConstraintXController.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/ConstraintXController.java
new file mode 100644
index 0000000000000000000000000000000000000000..5742acf5e4888430d78c82c2aae2283d0d58b9e5
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/ConstraintXController.java
@@ -0,0 +1,299 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Shape;
+
+public class ConstraintXController extends ConstraintController {
+
+	private int dy = 10;
+	
+	protected Line leftline, rightline;
+	protected Circle leftcircle, rightcircle;
+	
+	public ConstraintXController(VisBody group) {
+		super(group);
+		
+		leftline = new Line();
+		rightline = new Line();
+		leftcircle = new Circle();
+		rightcircle = new Circle();
+		leftcircle.radiusProperty().set(4);
+		rightcircle.radiusProperty().set(4);
+		
+		leftline.strokeProperty().set(Color.RED);
+		rightline.strokeProperty().set(Color.RED);
+		leftcircle.fillProperty().set(Color.RED);
+		rightcircle.fillProperty().set(Color.RED);
+
+		getChildren().add(leftline);
+		getChildren().add(rightline);
+		getChildren().add(leftcircle);
+		getChildren().add(rightcircle);
+		
+		group.getConstraintXProperty().addListener(new InvalidationListener()  {
+			@Override
+			public void invalidated(Observable observable)  {
+				type = group.getConstraintXProperty().get();
+				
+				if(type != Constraint.None && !group.getComponents().isEmpty()) {
+					if(group.getConstraintYProperty().get() == Constraint.None) {
+						group.reorderChildren(true);
+					}
+					refresh();
+					updateRight(0);
+				} else refresh();
+			}
+		});
+		
+		setVisible(false);
+		
+		group.distanceXProperty.addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				if(group.getComponents().isEmpty()) return;
+					
+				Mark mark = group.getComponents().get(Math.min(ConstraintController.xselectionIndex, group.getComponents().size() - 1));
+				activeMark = mark;	
+				group.invalidated(mark.getCoords().x);
+				group.updateLayout(mark);
+			}
+		});
+	}
+	
+	
+	@Override
+	public void translate(Line lineTrace, ConstraintHandle constraintHandler) {
+		
+		if(constraintHandler == ConstraintHandle.LEFT) {
+			double dx = lineTrace.getStartX() - lineTrace.getEndX();
+// TODO	: It does not find the correct Handler!!! That's all!!!		
+			group.distanceXProperty.set(distance_init + dx);
+			//group.invalidated(activeMark.getCoords().x);
+		}
+		else {
+			double dx = lineTrace.getEndX() - lineTrace.getStartX();
+			group.distanceXProperty.set(distance_init + dx);
+			//group.invalidated(activeMark.getCoords().x);
+		}
+	}
+	
+	
+	public void refresh() {
+		if(type == Constraint.None) return;
+		List<Mark> marks = group.getComponents();
+
+		if(marks.size() == 1) {
+			double width = marks.get(0).width();
+			if(type == Constraint.Spacing) group.distanceXProperty.set(0);
+			else group.distanceXProperty.set(width + 10); // TODO: This is arbitrary!!!
+		} else if(marks.size() > 1) {
+			if(type == Constraint.Spacing) {
+				group.distanceXProperty.set(marks.get(1).left() - marks.get(0).right());				
+			} else {
+				group.distanceXProperty.set(marks.get(1).getCoords().getX() - marks.get(0).getCoords().getX());
+			}
+		}
+	}
+	
+	@Override
+	public void setMark(Mark mark, boolean highlight) {
+		if(type == Constraint.None) {
+			 setVisible(false);
+			 return;
+		}
+			
+		
+		if(highlight) {			
+			activeMark = mark;
+			int index = group.getComponents().indexOf(mark);
+			
+			double ypos =  dy + group.getControlYPosition();
+			
+			if(index > 0) {
+				if(type == Constraint.Spacing) {
+					double left = group.getComponents().get(index).left();
+					
+					leftcircle.centerXProperty().set(left - group.distanceXProperty.get());
+					leftcircle.centerYProperty().set(ypos);
+		
+					leftline.startXProperty().set(left - group.distanceXProperty.get());
+					leftline.startYProperty().set(ypos);
+					leftline.endXProperty().set(left);
+					leftline.endYProperty().set(ypos);					
+				}
+				else {
+					double x = group.getComponents().get(index).getCoords().getX();
+					
+					leftcircle.centerXProperty().set(x - group.distanceXProperty.get());
+					leftcircle.centerYProperty().set(ypos);
+					
+					leftline.startXProperty().set(x - group.distanceXProperty.get());
+					leftline.startYProperty().set(ypos);
+					leftline.endXProperty().set(x);
+					leftline.endYProperty().set(ypos);						
+				}
+				
+				leftline.setVisible(true);
+				leftcircle.setVisible(true);
+			} else {
+				leftcircle.centerXProperty().set(-1000);
+				leftline.setVisible(false);
+				leftcircle.setVisible(false);
+			}
+		
+			if(index <  group.getComponents().size() - 1) {
+				if(type == Constraint.Spacing) {
+					double right = group.getComponents().get(index).right();
+					
+					rightline.startXProperty().set(right);
+					rightline.startYProperty().set(ypos);
+					rightline.endXProperty().set(right + group.distanceXProperty.get());
+					rightline.endYProperty().set(ypos);			
+					
+					rightcircle.centerXProperty().set(right + group.distanceXProperty.get());
+					rightcircle.centerYProperty().set(ypos);
+				}
+				else {
+					double x = group.getComponents().get(index).getCoords().getX();
+					
+					rightline.startXProperty().set(x);
+					rightline.startYProperty().set(ypos);
+					rightline.endXProperty().set(x + group.distanceXProperty.get());
+					rightline.endYProperty().set(ypos);	
+					
+					rightcircle.centerXProperty().set(x + group.distanceXProperty.get());
+					rightcircle.centerYProperty().set(ypos);
+				}	
+				
+				rightline.setVisible(true);
+				rightcircle.setVisible(true);
+			} else {
+				rightcircle.centerXProperty().set(100000);
+				rightline.setVisible(false);
+				rightcircle.setVisible(false);
+			}
+			
+			setVisible(true);
+		}
+		else {
+			activeMark = null;
+			setVisible(false);
+			flagSelection();
+		}
+	}
+		
+	@Override
+	public void updateMarkPositions(Mark mark) {
+		if(type == Constraint.None) {
+			return;
+		}
+
+		int index = group.getComponents().indexOf(mark);
+
+		updateLeft(index);
+		updateRight(index);
+	}
+	
+	
+	private void updateLeft(int index) {
+		Mark mark = group.getComponents().get(index);
+		if(mark == null) return;
+		
+		for(int i = index - 1; i >=0; --i) {
+			Mark mark_ = group.getComponents().get(i);
+			if(type == Constraint.Spacing) {
+				if(mark_ instanceof VisBody) { 
+					double dx = mark_.getCoords().getX() - mark_.left();
+					mark_.setPositionX(mark.left() - group.distanceXProperty.get() - mark_.width() + dx);
+				}
+				else {
+					switch(mark_.getCoords().getXRef()) {
+						case Center: mark_.setPositionX(mark.left() - group.distanceXProperty.get() - mark_.width()/2);
+							break;
+						case Left: mark_.setPositionX(mark.left() - group.distanceXProperty.get() - mark_.width());
+							break;
+						case Right: mark_.setPositionX(mark.left() - group.distanceXProperty.get());
+							break;
+					}
+				}
+			}
+			else {
+				if(mark_ != null) mark_.setPositionX(mark.getCoords().getX() - group.distanceXProperty.get());
+			}
+			mark = mark_;
+		}
+	}
+	
+	private void updateRight(int index) { 
+		if(group.getComponents().size() - 1 < index) return;
+		
+		Mark mark = group.getComponents().get(index);
+		for(int i = index + 1; i < group.getComponents().size(); ++i) {
+			Mark mark_ = group.getComponents().get(i);
+			if(type == Constraint.Spacing) {
+				if(mark_ instanceof VisBody) {
+					double dx = mark_.getCoords().getX() - mark_.left();
+					mark_.setPositionX(mark.right() + group.distanceXProperty.get() +  dx);
+				} 
+				else {
+					switch(mark_.getCoords().getXRef()) {
+						case Center: mark_.setPositionX(mark.right() + group.distanceXProperty.get() + mark_.width()/2);
+							break;
+						case Left: mark_.setPositionX(mark.right() + group.distanceXProperty.get());
+							break;
+						case Right: mark_.setPositionX(mark.right() + group.distanceXProperty.get() + mark_.width());
+							break;
+					}
+				}
+			}
+			else {				
+				mark_.setPositionX(mark.getCoords().getX() + group.distanceXProperty.get());
+			}
+			mark = mark_;
+		}
+	}
+
+
+	@Override
+	protected void selectHandle(Circle shape) {
+		super.selectHandle(shape);
+
+		if(shape == leftcircle) {			
+			distance_init = group.distanceXProperty.doubleValue();
+			activeMark.setConstraintControl(getSelf(), ConstraintHandle.LEFT);
+			flagSelection();
+		}
+		else {
+			distance_init = group.distanceXProperty.doubleValue();
+			activeMark.setConstraintControl(getSelf(), ConstraintHandle.RIGHT);
+			flagSelection();
+		}
+	}
+	
+	protected void flagSelection() {		
+		if(!ConstraintController.handlerhold && activeMark == null) {
+			xselectionIndex = 0;
+			xselectionPos = Double.MAX_VALUE;
+		}
+		else if(activeMark != null) {
+			xselectionIndex = group.getComponents().indexOf(activeMark);
+			xselectionPos = activeMark.getCoords().getX();
+		}
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/ConstraintYController.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/ConstraintYController.java
new file mode 100644
index 0000000000000000000000000000000000000000..60b1791fab6db84e9b18016feb9537b15eeec8ba
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/ConstraintYController.java
@@ -0,0 +1,322 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import java.util.List;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.types.DistributionProperty.Constraint;
+import fr.inria.structgraphics.ui.viscanvas.groupinteractors.ConstraintController.ConstraintHandle;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.EventHandler;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+
+public class ConstraintYController extends ConstraintController {
+
+	private int dx = -10;
+	
+	protected Line bottomline, topline;
+	protected Circle bottomcircle, topcircle;
+		
+	public ConstraintYController(VisBody group) {
+		super(group);
+		
+		bottomline = new Line();
+		topline = new Line();
+		bottomcircle = new Circle();
+		topcircle = new Circle();
+		bottomcircle.radiusProperty().set(4);
+		topcircle.radiusProperty().set(4);
+		
+		bottomline.strokeProperty().set(Color.RED);
+		topline.strokeProperty().set(Color.RED);
+		bottomcircle.fillProperty().set(Color.RED);
+		topcircle.fillProperty().set(Color.RED);
+
+		getChildren().add(bottomline);
+		getChildren().add(topline);
+		getChildren().add(bottomcircle);
+		getChildren().add(topcircle);
+		
+		group.getConstraintYProperty().addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				type = group.getConstraintYProperty().get();
+
+				if(type != Constraint.None && !group.getComponents().isEmpty()) {
+					if(group.getConstraintXProperty().get() == Constraint.None) {
+						group.reorderChildren(false);
+					}
+					refresh();
+					updateTop(0);
+				} else refresh();
+			}
+		});
+		
+		setVisible(false);
+		
+		group.distanceYProperty.addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) { 
+				if(group.getComponents().isEmpty()) return;
+				
+				Mark mark = group.getComponents().get(Math.min(ConstraintController.yselectionIndex, group.getComponents().size() - 1));
+				activeMark = mark;		
+				group.invalidated(mark.getCoords().y);
+				group.updateLayout(mark);
+			}
+		});
+	}
+		
+	
+	@Override
+	public void translate(Line lineTrace, ConstraintHandle constraintHandler) {
+		
+		if(constraintHandler == ConstraintHandle.UP) {
+			double dy = lineTrace.getStartY() - lineTrace.getEndY();
+			
+			group.distanceYProperty.set(distance_init + dy);
+			//group.invalidated(activeMark.getCoords().y);
+		}
+		else {
+			double dy = lineTrace.getEndY() - lineTrace.getStartY();
+			
+			group.distanceYProperty.set(distance_init + dy);
+			//group.invalidated(activeMark.getCoords().y);
+		}
+	}
+	
+	
+	@Override
+	public void refresh() {
+		if(type == Constraint.None) return;
+		List<Mark> marks = group.getComponents();
+		
+		if(marks.size() == 1) {
+			//double height = marks.get(0).height();
+			//if(type == Constraint.Spacing) group.distanceYProperty.set(0);
+			//else group.distanceYProperty.set(height + 10); // TODO: This is arbitrary!!!
+		} else if(marks.size() > 1) {
+			if(type == Constraint.Spacing) {
+				group.distanceYProperty.set(marks.get(1).bottom() - marks.get(0).top());
+			} else {
+				group.distanceYProperty.set(marks.get(1).getCoords().getY() - marks.get(0).getCoords().getY());
+			}
+		}
+		
+	}
+	
+	@Override
+	public void setMark(Mark mark, boolean highlight) {	
+		if(type == Constraint.None) {
+			 setVisible(false);
+			 return;
+		}
+		
+		if(highlight) {
+			activeMark = mark;
+			int index = group.getComponents().indexOf(mark);
+						
+			//ConstraintController.selectionIndex = index;
+			//System.err.println(activeMark + " ^^ " + selectionIndex);		
+			
+			double xpos =  dx + group.getControlXPosition();
+			
+			if(index > 0) {
+				if(type == Constraint.Spacing) {
+					double bottom = group.getComponents().get(index).bottom();
+					
+					bottomcircle.centerYProperty().set(-(bottom - group.distanceYProperty.get()));
+					bottomcircle.centerXProperty().set(xpos);
+		
+					bottomline.startYProperty().set(-(bottom - group.distanceYProperty.get()));
+					bottomline.startXProperty().set(xpos);
+					bottomline.endYProperty().set(-bottom);
+					bottomline.endXProperty().set(xpos);					
+				}
+				else {
+					double y = group.getComponents().get(index).getCoords().getY();
+					
+					bottomcircle.centerYProperty().set(-(y - group.distanceYProperty.get()));
+					bottomcircle.centerXProperty().set(xpos);
+					
+					bottomline.startYProperty().set(-(y - group.distanceYProperty.get()));
+					bottomline.startXProperty().set(xpos);
+					bottomline.endYProperty().set(-y);
+					bottomline.endXProperty().set(xpos);						
+				}
+				
+				bottomline.setVisible(true);
+				bottomcircle.setVisible(true);
+			} else {
+				bottomcircle.centerYProperty().set(-20000);
+				bottomline.setVisible(false);
+				bottomcircle.setVisible(false);
+			}
+		
+			if(index <  group.getComponents().size() - 1) {
+				if(type == Constraint.Spacing) {
+					double top = group.getComponents().get(index).top();
+					
+					topline.startYProperty().set(-top);
+					topline.startXProperty().set(xpos);
+					topline.endYProperty().set(-(top + group.distanceYProperty.get()));
+					topline.endXProperty().set(xpos);			
+					
+					topcircle.centerYProperty().set(-(top + group.distanceYProperty.get()));
+					topcircle.centerXProperty().set(xpos);
+				}
+				else {
+					double y = group.getComponents().get(index).getCoords().getY();
+					
+					topline.startYProperty().set(-y);
+					topline.startXProperty().set(xpos);
+					topline.endYProperty().set(-(y + group.distanceYProperty.get()));
+					topline.endXProperty().set(xpos);	
+					
+					topcircle.centerYProperty().set(-(y + group.distanceYProperty.get()));
+					topcircle.centerXProperty().set(xpos);
+				}	
+				
+				topline.setVisible(true);
+				topcircle.setVisible(true);
+			} else {
+				topcircle.centerYProperty().set(20000);
+				topline.setVisible(false);
+				topcircle.setVisible(false);
+			}
+			
+			setVisible(true);
+		}
+		else {
+			activeMark = null;
+			setVisible(false);
+			flagSelection();
+		}
+	}
+		
+	@Override
+	public void updateMarkPositions(Mark mark) {
+		if(type == Constraint.None) return;
+		int index = group.getComponents().indexOf(mark);
+/*
+		int index; 
+		if(mark.isHighlighted()) {
+			highlighted_group = group;
+			index = group.getComponents().indexOf(activeMark);
+			yselectionIndex = index;
+			yselectionPos = activeMark.getCoords().getY();
+		} else if(highlighted_group == group) {
+			return;
+		}
+		else index = getClosest(yselectionPos);*/
+						
+		updateBottom(index);
+		updateTop(index);		
+	}
+	
+	/*
+	private int getClosest(double y) {
+		double epsilon = 10;
+		double dist = Double.MAX_VALUE;
+		int index = -1;
+		
+		for(int i = 0; i < group.getComponents().size(); ++i) {
+			Mark mark = group.getComponentAt(i);
+			double d = Math.abs(mark.getCoords().getY() - y);
+			if(d < dist) {
+				index = i;
+				dist = d;
+			}
+		}
+		
+		if(dist < epsilon) return index;
+		else return Math.min(yselectionIndex, group.getComponents().size() - 1);
+	}*/
+	
+	private void updateBottom(int index) {
+		Mark mark = group.getComponents().get(index);
+		for(int i = index - 1; i >=0; --i) {
+			Mark mark_ = group.getComponents().get(i);
+			if(type == Constraint.Spacing) {
+				if(mark_ instanceof VisBody) { 
+					double dy = mark_.getCoords().getY() - mark_.bottom();
+					mark_.setPositionY(mark.bottom() - group.distanceYProperty.get() - mark_.height() + dy);
+				}
+				else {
+					switch(mark_.getCoords().getYRef()) {
+						case Center: mark_.setPositionY(mark.bottom() - group.distanceYProperty.get() - mark_.height()/2);
+							break;
+						case Bottom: mark_.setPositionY(mark.bottom() - group.distanceYProperty.get() - mark_.height());
+							break;
+						case Top: mark_.setPositionY(mark.bottom() - group.distanceYProperty.get());
+							break;
+					}
+				}
+			}
+			else {
+				mark_.setPositionY(mark.getCoords().getY() - group.distanceYProperty.get());
+			}
+			mark = mark_;
+		}
+	}
+	
+	private void updateTop(int index) { 
+		Mark mark = group.getComponents().get(index);
+		for(int i = index + 1; i < group.getComponents().size(); ++i) {
+			Mark mark_ = group.getComponents().get(i);
+			if(type == Constraint.Spacing) {
+				if(mark_ instanceof VisBody) {
+					double dy = mark_.getCoords().getY() - mark_.bottom();
+					mark_.setPositionY(mark.top() + group.distanceYProperty.get() +  dy);
+				} 
+				else {
+					switch(mark_.getCoords().getYRef()) {
+						case Center: mark_.setPositionY(mark.top() + group.distanceYProperty.get() + mark_.height()/2);
+							break;
+						case Bottom: mark_.setPositionY(mark.top() + group.distanceYProperty.get());
+							break;
+						case Top: mark_.setPositionY(mark.top() + group.distanceYProperty.get() + mark_.height());
+							break;
+					}
+				}
+			}
+			else {
+				mark_.setPositionY(mark.getCoords().getY() + group.distanceYProperty.get());
+			}
+			mark = mark_;
+		}
+	}
+
+	@Override
+	protected void selectHandle(Circle shape) {
+		super.selectHandle(shape);
+		
+		if(shape == bottomcircle) {
+			distance_init = group.distanceYProperty.get();
+			activeMark.setConstraintControl(getSelf(), ConstraintHandle.DOWN);
+			flagSelection();
+		}
+		else {
+			distance_init = group.distanceYProperty.get();
+			activeMark.setConstraintControl(getSelf(), ConstraintHandle.UP);
+			flagSelection();
+		}
+	}
+	
+	protected void flagSelection() {		
+		if(!ConstraintController.handlerhold && activeMark == null) {
+			yselectionIndex = 0;
+			yselectionPos = Double.MAX_VALUE;
+		}
+		else if(activeMark != null) {
+			yselectionIndex = group.getComponents().indexOf(activeMark);
+			yselectionPos = activeMark.getCoords().getY();
+		}
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/GroupInteractor.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/GroupInteractor.java
new file mode 100644
index 0000000000000000000000000000000000000000..facb43af80dbd1924d28cbe1193152f9fb9a92c0
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/GroupInteractor.java
@@ -0,0 +1,122 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import fr.inria.structgraphics.graphics.Container;
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.types.AlignmentProperty;
+import fr.inria.structgraphics.ui.utils.Cloner;
+import javafx.scene.Group;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+
+public class GroupInteractor extends BodyInteractor {
+
+	private Line xAxis, yAxis;
+		
+	public GroupInteractor(VisGroup group) {
+		super(group);
+	}
+	
+	
+	@Override
+	protected void drawHandler() {			
+		super.drawHandler();
+		handler.setStroke(group.isExternal() ? COL3 : COL3);
+	}
+	
+	
+	protected boolean isXNeeded() {
+		if(group.isExternal()) return true;
+		else {
+			Container container = group.getContainer();
+			if(container instanceof VisGroup && ((VisGroup)container).getAlignYProperty().get() == AlignmentProperty.XSticky.Yes)
+				return false;
+			
+			return true;
+		}
+	}
+	
+	protected boolean isYNeeded() {
+		if(group.isExternal()) return true;
+		else {
+			Container container = group.getContainer();
+			if(container instanceof VisGroup && ((VisGroup)container).getAlignXProperty().get() == AlignmentProperty.YSticky.Yes)
+				return false;
+			
+			return true;
+		}
+	}
+	
+	@Override
+	protected void drawBoundary() {
+		xAxis = new Line(0, 0, 100, 0);
+		xAxis.startXProperty().bind(left);
+		xAxis.endXProperty().bind(right);	
+		getChildren().add(xAxis);
+		xAxis.setStroke(group.isExternal() ? COL3 : COL3);
+		if(!group.isExternal()) xAxis.getStrokeDashArray().addAll(2d);
+		else xAxis.getStrokeDashArray().clear();
+		
+		yAxis = new Line(0, 0, 0, -100);
+		yAxis.startYProperty().bind(bottom);
+		yAxis.endYProperty().bind(top);
+		getChildren().add(yAxis);
+		yAxis.setStroke(group.isExternal() ? COL3 : COL3);
+		if(!group.isExternal()) yAxis.getStrokeDashArray().addAll(2d);
+		else yAxis.getStrokeDashArray().clear();
+		
+		addToGhost(Cloner.clone(xAxis));
+		addToGhost(Cloner.clone(yAxis));
+	}
+	
+	public Line getXAxis() {
+		return xAxis;
+	}
+	
+	public Line getYAxis() {
+		return yAxis;
+	}
+	
+	@Override
+	public void refresh() {		
+		super.refresh();
+		addToGhost(Cloner.clone(xAxis));
+		addToGhost(Cloner.clone(yAxis));
+		
+		boolean isX = isXNeeded();
+		boolean isY = isYNeeded();
+		
+		xAxis.setVisible(isX);
+		yAxis.setVisible(isY);
+		handler.setVisible(isX || isY);
+	}
+	
+	@Override
+	public void setHighlight(boolean highlight) { 
+		super.setHighlight(highlight && handler.isVisible());
+	}
+	
+	@Override
+	public Group createCopy(double dx, double dy) { 
+		Group group = new Group();
+		Circle handler_ = new Circle(dx, dy, 10);
+		Line xAxis_ = new Line(xAxis.getStartX() + dx, xAxis.getStartY() + dy, xAxis.getEndX() + dx, xAxis.getEndY() + dy);
+		Line yAxis_ = new Line(yAxis.getStartX() + dx, yAxis.getStartY() + dy, yAxis.getEndX() + dx, yAxis.getEndY() + dy);
+			
+		group.getChildren().add(handler_);
+		group.getChildren().add(xAxis_);
+		group.getChildren().add(yAxis_);
+		
+		return group;
+	}
+
+	@Override
+	public double getWidth() {
+		return Math.abs(xAxis.getEndX() - xAxis.getStartX());
+	}
+	
+	@Override
+	public double getHeight() {
+		return Math.abs(yAxis.getEndY() - yAxis.getStartY());
+	}
+}
+
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/LabelCollection.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/LabelCollection.java
new file mode 100644
index 0000000000000000000000000000000000000000..31d530f29be2facfa5bd90a3466668196f417abc
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/LabelCollection.java
@@ -0,0 +1,41 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import javafx.beans.property.Property;
+import javafx.scene.Group;
+
+public class LabelCollection extends Group {
+
+	private Mark mark;
+	private Map<DataVariable, NodeLabel> labels = new HashMap<DataVariable, NodeLabel>();
+	
+	public LabelCollection(Mark mark) {
+		this.mark = mark;
+	}
+	
+	public void showVariable(DataVariable variable, Property property) {
+		NodeLabel node = labels.get(variable);
+		if(node != null && !variable.nodeShownProperty.get()) {
+			getChildren().remove(node);
+			labels.remove(variable);
+		}
+		else if(variable.nodeShownProperty.get()) {
+			NodeLabel label = new NodeLabel(mark, variable, property);
+			getChildren().add(label);
+			labels.put(variable, label);
+		}		
+	}
+	
+	public void update() {
+		for(NodeLabel label: labels.values())
+			label.update();
+	}
+
+	public boolean isLabelShown(DataVariable variable) {
+		return labels.get(variable) != null;
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/Legend.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/Legend.java
new file mode 100644
index 0000000000000000000000000000000000000000..d072cf5ac7dfb6aee97df3cf0187bad0c93ecc47
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/Legend.java
@@ -0,0 +1,158 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import java.util.SortedSet;
+import java.util.TreeMap;
+
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.ui.spreadsheet.ComparableDataValue;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import fr.inria.structgraphics.ui.spreadsheet.DiscreteTransformation;
+import fr.inria.structgraphics.ui.spreadsheet.MappingProperty;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable.DataType;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.geometry.Bounds;
+import javafx.geometry.Pos;
+import javafx.scene.Group;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.scene.text.Text;
+
+public class Legend extends Group {
+	protected Font textFont = new Font(12);
+	protected Font labelFont = Font.font("Verdana", FontWeight.BOLD, 12);
+	protected Color stroke = Color.GREY;
+	protected double rectStrokeWidth = 0.8;
+	protected Color textColor = Color.GREY;
+	
+	protected double vgap = 4;
+	protected double hgap = 2;
+	
+	protected double iconSize = 12;
+	
+	protected Text label;
+	
+	protected VBox values;
+	
+	protected VisBody group;
+	protected DataVariable variable;
+	
+	public Legend(VisBody group, DataVariable variable) {
+		this.group = group;
+		this.variable = variable;
+			
+		values = new VBox(vgap);
+		
+		label = new Text();
+		label.setFont(labelFont);
+		label.setFill(textColor);
+		
+		getChildren().add(values);
+			
+		updateCaption();
+		updateValues();
+	}
+	
+	public Bounds bounds() {
+		return getLayoutBounds();
+	}
+	
+	public void update() { 
+		updateCaption();
+		updateValues();
+	}
+	
+	private void updateValues() {		
+		values.getChildren().clear();
+		
+		values.getChildren().add(label);
+		
+		if(variable.getType().equals(DataType.Functional) && variable.isNumeric()) {
+			// TODO: ....
+
+		} else {
+			DiscreteTransformation transform = (DiscreteTransformation)variable.transformationProperty().get();
+			TreeMap<MappingProperty, StringProperty> map = transform.getMap();
+			
+			for(MappingProperty key: map.keySet()) {
+				
+				StringProperty prop = map.get(key);
+				Text textValue = new Text(prop.get());
+				prop.addListener(new ChangeListener<String>() {
+
+					@Override
+					public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
+						textValue.setText(newValue);
+					}
+				});
+			
+				textValue.setFont(textFont);
+				textValue.setFill(textColor);
+				
+				Group icon = new LegendIcon(iconSize, variable, key);
+				textValue.translateXProperty().set(icon.getTranslateX());
+				
+				HBox box = new HBox(hgap);
+				box.alignmentProperty().set(Pos.CENTER_LEFT);
+				box.translateXProperty().set(hgap);
+				
+				box.getChildren().add(icon);
+				box.getChildren().add(textValue);
+				values.getChildren().add(box);
+			}
+		}
+	}
+	
+	
+	private void updateValues2() {		
+		values.getChildren().clear();
+		
+		values.getChildren().add(label);
+		
+		if(variable.getType().equals(DataType.Functional) && variable.isNumeric()) {
+			// TODO: ....
+
+		} else {
+			SortedSet<ComparableDataValue> range = variable.getDiscreteValues();
+			for(ComparableDataValue val: range) {
+				
+				Text textValue = new Text(variable.transformationProperty().get().toData(val.getValue()));
+				
+				val.getProperty().addListener(new InvalidationListener() {
+					@Override
+					public void invalidated(Observable observable) {
+						textValue.setText(variable.transformationProperty().get().toData(val.getValue()));						
+					}
+				});
+				
+				
+				textValue.setFont(textFont);
+				textValue.setFill(textColor);
+				
+				Group icon = new LegendIcon(iconSize, variable, val);
+				
+				HBox box = new HBox(hgap);
+				box.alignmentProperty().set(Pos.CENTER_LEFT);
+				box.translateXProperty().set(hgap);
+				
+				box.getChildren().add(icon);
+				box.getChildren().add(textValue);
+				values.getChildren().add(box);
+			}
+		}
+	}
+	
+	private void updateCaption() {
+		label.textProperty().unbind();
+		label.textProperty().bind(variable.getName(0));
+		
+		label.xProperty().set(0);
+		label.yProperty().set(vgap + label.getLayoutBounds().getHeight());		
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/LegendCollection.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/LegendCollection.java
new file mode 100644
index 0000000000000000000000000000000000000000..19036d27df9b229db69c6d74a711b96cca32f363
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/LegendCollection.java
@@ -0,0 +1,51 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.scene.layout.VBox;
+
+public class LegendCollection extends VBox {
+	
+	private Map<DataVariable, Legend> map = new Hashtable<>();
+	private VisBody vgroup;
+	
+	private double xGap = 20;
+	
+	private final static double VGap = 8;
+	
+	public LegendCollection(VisBody group) {
+		super(VGap);
+		this.vgroup = group;
+				
+		translateYProperty().bind(vgroup.getInteractor().top);
+		vgroup.getInteractor().right.addListener(new InvalidationListener() {
+			@Override
+			public void invalidated(Observable observable) {
+				translateXProperty().set(xGap + vgroup.getInteractor().right.get());
+			}
+		});
+	}
+	
+	public void addLegend(DataVariable variable) {
+		if(map.containsKey(variable)) {
+			Legend legend = map.get(variable);
+			map.remove(variable);
+			getChildren().remove(legend);
+		}
+		else {
+			Legend legend = new Legend(vgroup, variable);
+			map.put(variable, legend);
+			getChildren().add(legend);
+		}
+	}
+	
+	public void update() {
+		for(Legend legend: map.values())
+			legend.update();
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/LegendIcon.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/LegendIcon.java
new file mode 100644
index 0000000000000000000000000000000000000000..1fa5c83641809480b7b9fb0b3a87fc316df017bb
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/LegendIcon.java
@@ -0,0 +1,110 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import fr.inria.structgraphics.types.ShapeProperty;
+import fr.inria.structgraphics.ui.spreadsheet.ComparableDataValue;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import fr.inria.structgraphics.ui.spreadsheet.MappingProperty;
+import javafx.scene.Group;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.shape.Shape;
+
+public class LegendIcon extends Group {
+
+	private double size;
+
+	public LegendIcon(double size, DataVariable variable, MappingProperty prop) {
+		this.size = size;
+		
+		if(variable.isShape()) createShape((ShapeProperty.Type)prop.getValue());
+		else if(variable.isThickness()) createThickness((double)prop.getValue());
+		else if(variable.isFill()) createFill((Color)prop.getValue());
+		else if(variable.isStroke()) createStroke((Color)prop.getValue());
+		else createSize((double)prop.getValue());
+	}
+	
+	
+	public LegendIcon(double size, DataVariable variable, ComparableDataValue value) {
+		this.size = size;
+		
+		if(variable.isShape()) createShape((ShapeProperty.Type)value.getValue());
+		else if(variable.isThickness()) createThickness((double)value.getValue());
+		else if(variable.isFill()) createFill((Color)value.getValue());
+		else if(variable.isStroke()) createStroke((Color)value.getValue());
+		else createSize((double)value.getValue());
+	}
+	
+
+	private void createStroke(Color value) {
+		Line line = new Line(0, 0, size, size);
+		line.setStrokeWidth(1);
+		line.setStroke(value);
+		
+		getChildren().add(line);
+	}
+
+	
+	private void createFill(Color value) {
+		Rectangle rect = new Rectangle(size, size);
+		rect.setStrokeWidth(.5);
+		rect.setStroke(Color.GRAY);
+		rect.setFill(value);
+		
+		getChildren().add(rect);
+	}
+
+	private void createThickness(double value) {
+		Line line = new Line(0, 0, size, size);
+		line.setStrokeWidth(value);
+		line.setStroke(Color.BLACK);
+		
+		getChildren().add(line);
+	}
+
+	private void createSize(double value) {
+		Circle circle = new Circle(0, 0, value/2);
+		this.translateXProperty().set(-value/2);
+		circle.setFill(null);
+		circle.setStroke(Color.GRAY);
+		
+		getChildren().add(circle);
+	}
+
+	
+	private void createShape(ShapeProperty.Type shapeType) {
+		Shape shape = null;
+		
+		switch(shapeType) {
+			case Ellipse:
+				shape = new Circle(size/2, size/2, size/2);
+				break;
+				
+			case Triangle:
+				Path path = new Path();
+				path.getElements().add(new MoveTo(size/2, 0));
+				path.getElements().add(new LineTo(size, size));
+				path.getElements().add(new LineTo(0, size));
+				path.getElements().add(new LineTo(size/2, 0));
+				shape = path;
+				break;
+				
+			default:
+				shape = new Rectangle(size, size);
+				shape.setStrokeWidth(.6);
+				shape.setStroke(Color.GRAY);
+				shape.setFill(null);
+				break;
+		}
+		
+		shape.setStrokeWidth(.6);
+		shape.setStroke(Color.GRAY);
+		shape.setFill(null);
+		
+		getChildren().add(shape);
+	}
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/NodeLabel.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/NodeLabel.java
new file mode 100644
index 0000000000000000000000000000000000000000..5132eb90c898f9f0b0c7ab6a108e12ba913208e1
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/NodeLabel.java
@@ -0,0 +1,133 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import fr.inria.structgraphics.graphics.LineConnectedCollection;
+import fr.inria.structgraphics.graphics.Mark;
+import fr.inria.structgraphics.graphics.ShapeMark;
+import fr.inria.structgraphics.graphics.VisBody;
+import fr.inria.structgraphics.graphics.VisCollection;
+import fr.inria.structgraphics.graphics.VisFrame;
+import fr.inria.structgraphics.ui.spreadsheet.DataVariable;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.Property;
+import javafx.scene.Group;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.scene.text.Text;
+import javafx.scene.text.TextAlignment;
+
+public class NodeLabel extends Group implements InvalidationListener {
+
+	protected Font labelFont = Font.font("Verdana", 10);
+	protected Font collectionFont = Font.font("Verdana", FontWeight.BOLD, 11);
+	
+	protected Color textColor = Color.GREY;
+		
+	private Text text;
+	private Mark mark;
+	protected DataVariable variable;
+	protected Property property;
+	
+	public NodeLabel(Mark mark, DataVariable variable, Property property) {
+		this.mark = mark;
+		this.variable = variable;
+		this.property = property;
+		
+		text = new Text();
+		text.setFont((mark instanceof VisCollection) ? collectionFont : labelFont);
+			
+		if(variable.isStroke() || variable.isFill()) text.setFill((Color)property.getValue());
+		else {
+			text.fillProperty().bind(((VisFrame)mark.getRoot()).stroke);
+		}
+		text.setTextAlignment(TextAlignment.CENTER);
+		
+		getChildren().add(text);
+		
+		showVariable(variable, property);
+	}
+	
+	public void showVariable(DataVariable variable, Property property) {		
+		variable.transformationProperty().addListener(this);
+		update();
+	}
+	
+	public void update() {	
+		// TODO: this is a quick hack to show positive only values for the width variable
+		// TODO I need an explict interaction from behalf of the user
+		String value; 
+		if(variable.isWidth()) {
+			value = variable.transformationProperty().get().toData(Math.abs((double)property.getValue()));
+		} else {
+			value = variable.isID() ? variable.transformationProperty().get().toData(mark.id.get()) :
+				variable.transformationProperty().get().toData(property.getValue()) ;
+		}
+		
+		text.setText(value);
+		
+		text.xProperty().set(-text.getLayoutBounds().getWidth()/2);
+		text.yProperty().set(text.getLayoutBounds().getHeight()/2);			
+	
+		this.translateXProperty().set(0);
+		this.translateYProperty().set(0);
+		
+		if(variable.isStroke() && mark instanceof VisCollection) {
+			text.setTextAlignment(TextAlignment.LEFT);
+			
+			Mark child = ((VisCollection)mark).getComponents().get(((VisCollection)mark).getComponents().size() - 1);
+			double dx = child.left() - mark.coords.getX() + text.getLayoutBounds().getWidth()/2 + 25;
+			this.translateXProperty().set(dx);
+			
+			double dy =  (-child.coords.getY() + mark.coords.getY()) - text.getLayoutBounds().getHeight()/4;
+			this.translateYProperty().set(dy);
+		}
+		else if(mark instanceof VisBody /*&& variable.isID()*/) {
+			double dx = (mark.left() + mark.right())/2 - mark.coords.getX();
+			this.translateXProperty().set(dx);
+			
+			double dy =  (-mark.top() + mark.coords.getY()) - text.getLayoutBounds().getHeight() - 8;
+			this.translateYProperty().set(dy);
+		}
+		else if(variable.isHeight()) {
+			VisBody container = ((ShapeMark)mark).getRootVirtualGroup();
+			if(mark instanceof ShapeMark && (container instanceof LineConnectedCollection) 
+					&& ((LineConnectedCollection)container).hasConnections()) {
+				if(((ShapeMark)mark).hasOutwardConnections()) {
+					text.setTextAlignment(TextAlignment.RIGHT);
+					this.translateXProperty().set(-mark.width()/2 - text.getLayoutBounds().getWidth()/2 - 3);
+				} else {					
+					text.setTextAlignment(TextAlignment.LEFT);
+					this.translateXProperty().set(mark.width()/2 + text.getLayoutBounds().getWidth()/2 + 3);
+				}
+			}
+			else {
+				if(mark.height.get() > 0) this.translateYProperty().set(-mark.height()/2 - text.getLayoutBounds().getHeight());
+				else this.translateYProperty().set(-mark.height()/2 + text.getLayoutBounds().getHeight()/2);
+			}
+		} else if(variable.isX() || variable.isY()) {
+			this.translateYProperty().set(mark.height()/2 + text.getLayoutBounds().getHeight()/2);
+		} else if(variable.isWidth()) {
+			this.translateYProperty().set(-text.getLayoutBounds().getHeight()/4);
+			if(mark.width() > 0) this.translateXProperty().set(mark.width()/2 + text.getLayoutBounds().getWidth()/2 + 3);
+			else {
+				text.setTextAlignment(TextAlignment.RIGHT);
+				this.translateXProperty().set(mark.width()/2 - text.getLayoutBounds().getWidth()/2 - 3);
+			}
+		} else if(mark instanceof ShapeMark && variable.isConnectionNodeID()) {
+			if(((ShapeMark)mark).hasOutwardConnections()) {
+				text.setTextAlignment(TextAlignment.LEFT);
+				this.translateXProperty().set(mark.width()/2 + text.getLayoutBounds().getWidth()/2 + 3);
+			} else {
+				text.setTextAlignment(TextAlignment.RIGHT);
+				this.translateXProperty().set(-mark.width()/2 - text.getLayoutBounds().getWidth()/2 - 3);
+			}
+		}
+	}
+
+	@Override
+	public void invalidated(Observable observable) {
+		update();
+	}
+	
+}
diff --git a/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/SimpleGroupInteractor.java b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/SimpleGroupInteractor.java
new file mode 100644
index 0000000000000000000000000000000000000000..ae8fa308ef6f80b9b7a278fd8d526c189fecfe78
--- /dev/null
+++ b/src/fr/inria/structgraphics/ui/viscanvas/groupinteractors/SimpleGroupInteractor.java
@@ -0,0 +1,111 @@
+package fr.inria.structgraphics.ui.viscanvas.groupinteractors;
+
+import fr.inria.structgraphics.graphics.VisGroup;
+import fr.inria.structgraphics.ui.utils.Cloner;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.Group;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Rectangle;
+
+public class SimpleGroupInteractor extends BodyInteractor {
+
+	private Rectangle boundary;
+			
+	public SimpleGroupInteractor(VisGroup group) {
+		super(group);
+	}
+	
+	private void updateBoundary() {
+		boundary.xProperty().set(left.get());
+		boundary.yProperty().set(top.get());
+		boundary.widthProperty().set(right.get() - left.get());
+		boundary.heightProperty().set(bottom.get() - top.get());
+	}
+	
+	@Override
+	protected void drawHandler() {			
+		if(group.getContainer() instanceof VisGroup) {
+			handler = new Circle(0, 0, 0);	
+			handler.setFill(null);
+			handler.setStroke(null);
+		}
+		else {
+			handler = new Circle(0, 0, 6);	
+			handler.setFill(new Color(1, 1, 1, 0.1));
+			handler.setStroke(Paint.valueOf("#303F9F"));
+		}
+		
+		getChildren().add(handler);
+		addToGhost(Cloner.clone(handler));
+	}
+	
+	
+	@Override
+	protected void drawBoundary() { 
+		boundary = new Rectangle(0,0,0,0);
+		updateBoundary();
+		
+		left.addListener(new ChangeListener<Number>() {
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				updateBoundary();
+			}
+		});
+		right.addListener(new ChangeListener<Number>() {
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				updateBoundary();
+			}
+		});
+		top.addListener(new ChangeListener<Number>() {
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				updateBoundary();
+			}
+		});
+		bottom.addListener(new ChangeListener<Number>() {
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				updateBoundary();
+			}
+		});
+		
+		getChildren().add(boundary);
+		
+		boundary.strokeWidthProperty().set(0.3);
+		boundary.strokeProperty().set(Paint.valueOf("#303F9F"));		
+		boundary.setFill(null);
+		boundary.getStrokeDashArray().addAll(2d);
+				
+		addToGhost(Cloner.clone(boundary));
+	}
+		
+	@Override
+	public void refresh() {		
+		super.refresh();
+		addToGhost(Cloner.clone(boundary));
+	}
+	
+	@Override
+	public Group createCopy(double dx, double dy) { 
+		Group group = new Group();
+		Circle handler_ = new Circle(dx, dy, 6);
+		
+		Rectangle boundary_ = new Rectangle(boundary.getX() + dx, boundary.getY() + dy, boundary.getWidth(), boundary.getHeight());
+		
+		group.getChildren().add(handler_);
+		group.getChildren().add(boundary_);
+		
+		return group;
+	}
+
+	@Override
+	public double getWidth() { // TODO
+		return Math.abs(boundary.widthProperty().get());
+	}
+	
+	@Override
+	public double getHeight() {
+		return Math.abs(boundary.heightProperty().get());
+	}
+
+}
diff --git a/src/impl/build/transifex/JSON.java b/src/impl/build/transifex/JSON.java
new file mode 100644
index 0000000000000000000000000000000000000000..044bf30f0ee42f24bfc267c33541e12dd6611539
--- /dev/null
+++ b/src/impl/build/transifex/JSON.java
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.build.transifex;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+ 
+class JSON {
+    private static final Pattern PAT_INTEGER = Pattern.compile("[-+]?[0-9]+|0[Xx][0-9]+"); //$NON-NLS-1$
+    private static final Pattern PAT_DOUBLE = Pattern.compile("[+-]?[0-9]+([Ee][+-]?[0-9]+)?|[+-]?[0-9]*\\.[0-9]*([Ee][+-]?[0-9]+)?"); //$NON-NLS-1$
+    private static final Pattern PAT_STRING = Pattern.compile("\"([^\\\\]+\\\\[\"'\\\\])*[^\"]*\"|'([^\\\\]+\\\\[\"'\\\\])*[^']*'"); //$NON-NLS-1$
+    private static final Pattern PAT_BOOL = Pattern.compile("(true)|(false)"); //$NON-NLS-1$
+
+    private static Object parse(String s, int[] start, Matcher integerMatcher, Matcher doubleMatcher, Matcher stringMatcher, Matcher booleanMatcher) {
+        char[] c = s.toCharArray();
+        skipSpace(s, start);
+        if (c[start[0]] == '[') {
+            start[0]++;
+            ArrayList<Object> a = new ArrayList<>();
+            if (c[start[0]] == ']') {
+                start[0]++;
+                return a;
+            }
+            while (true) {
+                a.add(parse(s, start, integerMatcher, doubleMatcher, stringMatcher, booleanMatcher));
+                boolean crlf = skipSpace(s, start);
+                char p = c[start[0]];
+                if (p == ']') {
+                    start[0]++;
+                    return a;
+                }
+                if (p == ',')
+                    start[0]++;
+                else if (!crlf)
+                    throw new IllegalStateException(", or ] expected"); //$NON-NLS-1$
+            }
+        } else if (c[start[0]] == '{') {
+            start[0]++;
+            HashMap<String, Object> a = new HashMap<>();
+            while (true) {
+                String field = (String) parse(s, start, integerMatcher, doubleMatcher, stringMatcher, booleanMatcher);
+                boolean crlf = skipSpace(s, start);
+                if (c[start[0]] == ':') {
+                    start[0]++;
+                    a.put(field, parse(s, start, integerMatcher, doubleMatcher, stringMatcher, booleanMatcher));
+                    crlf = skipSpace(s, start);
+                } else
+                    a.put(field, ""); //$NON-NLS-1$
+                char p = c[start[0]];
+                if (p == '}') {
+                    start[0]++;
+                    return a;
+                }
+                if (p == ',')
+                    start[0]++;
+                else if (!crlf) {
+                    start[0]++;
+//                    throw new IllegalStateException(", or } expected at " + start[0]); //$NON-NLS-1$
+                }
+            }
+        }
+        if (integerMatcher.find(start[0])) {
+            String substring = match(start, s, integerMatcher);
+            if (substring != null) return Integer.valueOf(substring);
+        }
+        if (doubleMatcher.find(start[0])) {
+            String substring = match(start, s, doubleMatcher);
+            if (substring != null) return Double.valueOf(substring);
+        }
+        if (stringMatcher.find(start[0])) {
+            String substring = match(start, s, stringMatcher);
+            if (substring != null) return substring.substring(1, substring.length() - 1);
+        }
+        if (booleanMatcher.find(start[0])) {
+            String substring = match(start, s, booleanMatcher);
+            if (substring != null) return Boolean.valueOf(substring);
+        }
+//        throw new IllegalStateException("unexpected end of data"); //$NON-NLS-1$
+        return null;
+    }
+
+    private static String match(int[] start, String s, Matcher matcher) {
+        int ms = matcher.start();
+        int me = matcher.end();
+        if (start[0] == ms) {
+            start[0] = me;
+            return s.substring(ms, me);
+        }
+        return null;
+    }
+
+    public static boolean skipSpace(String s, int[] start) {
+        boolean ret = false;
+        while (true) {
+            char c = s.charAt(start[0]);
+            boolean crlf = (c == '\r') || (c == '\n');
+            if ((c != ' ') && !crlf)
+                break;
+            if (crlf)
+                ret = true;
+            start[0]++;
+        }
+        return ret;
+    }
+
+    @SuppressWarnings("unchecked")
+	public static <T> T parse(String json) {
+        Matcher integerMatcher = PAT_INTEGER.matcher(json);
+        Matcher doubleMatcher = PAT_DOUBLE.matcher(json);
+        Matcher stringMatcher = PAT_STRING.matcher(json);
+        Matcher booleanMatcher = PAT_BOOL.matcher(json);
+        return (T) parse(json, new int[]{0}, integerMatcher, doubleMatcher, stringMatcher, booleanMatcher);
+    }
+}
\ No newline at end of file
diff --git a/src/impl/build/transifex/Transifex.java b/src/impl/build/transifex/Transifex.java
new file mode 100644
index 0000000000000000000000000000000000000000..37e46964e8f69825c9b65c66b9228273a9496cf4
--- /dev/null
+++ b/src/impl/build/transifex/Transifex.java
@@ -0,0 +1,179 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.build.transifex;
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.util.Base64;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+public class Transifex {
+    
+    private static final String CHARSET             = "ISO-8859-1"; //$NON-NLS-1$
+    private static final String FILE_NAME           = "controlsfx_%1s.utf8"; //$NON-NLS-1$
+    private static final String NEW_LINE            = System.getProperty("line.separator"); //$NON-NLS-1$
+
+    private static final String BASE_URI            = "https://www.transifex.com/api/2/"; //$NON-NLS-1$
+    private static final String PROJECT_PATH        = BASE_URI + "project/controlsfx/resource/controlsfx-core"; // list simple project details //$NON-NLS-1$
+    private static final String PROJECT_DETAILS     = BASE_URI + "project/controlsfx/resource/controlsfx-core?details"; // list all project details //$NON-NLS-1$
+    private static final String LIST_TRANSLATIONS   = BASE_URI + "project/controlsfx/languages/"; // list all translations //$NON-NLS-1$
+    private static final String GET_TRANSLATION     = BASE_URI + "project/controlsfx/resource/controlsfx-core/translation/%1s?file"; // gets a translation for one language //$NON-NLS-1$
+    private static final String TRANSLATION_STATS   = BASE_URI + "project/controlsfx/resource/controlsfx-core/stats/%1s/"; // gets a translation for one language //$NON-NLS-1$
+
+    private static final String USERNAME            = System.getProperty("transifex.username"); //$NON-NLS-1$
+    private static final String PASSWORD            = System.getProperty("transifex.password"); //$NON-NLS-1$
+    private static final boolean FILTER_INCOMPLETE_TRANSLATIONS = Boolean.parseBoolean(System.getProperty("transifex.filterIncompleteTranslations", "true"));
+
+    public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
+        new Transifex().doTransifexCheck();
+    }
+        
+    @SuppressWarnings("unchecked")
+    private void doTransifexCheck() {
+        System.out.println("=== Starting Transifex Check ==="); //$NON-NLS-1$
+        
+        if (USERNAME == null || PASSWORD == null || USERNAME.isEmpty() || PASSWORD.isEmpty()) {
+            System.out.println("  transifex.username and transifex.password system properties must be specified"); //$NON-NLS-1$
+            return;
+        }
+        
+        System.out.println("  Filtering out incomplete translations: " + FILTER_INCOMPLETE_TRANSLATIONS);
+        
+        Map<String,Object> projectDetails = JSON.parse(transifexRequest(PROJECT_DETAILS));
+        List<Map<String, String>> availableLanguages = (List<Map<String, String>>) projectDetails.get("available_languages");
+        
+        // main loop
+        availableLanguages.parallelStream()
+                .map(map -> map.get("code")) //$NON-NLS-1$
+                .filter(this::filterOutIncompleteTranslations)
+                .forEach(this::downloadTranslation);
+        
+        System.out.println("Transifex Check Complete"); //$NON-NLS-1$
+    }
+    
+    private String transifexRequest(String request, Object... args) {
+        Function<InputStream, String> consumer = inputStream -> {
+            StringBuilder response = new StringBuilder(); 
+            try(BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream)) ) {
+                String line;
+                while((line = rd.readLine()) != null) {
+                    response.append(line);
+                    response.append(NEW_LINE);
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            } 
+
+            return response.toString();
+        };
+        return performTransifexTask(consumer, request, args);
+    }
+    
+    private static <T> T performTransifexTask(Function<InputStream, T> consumer, String request, Object... args) {
+        request = String.format(request, args);
+        
+        URL url;
+        HttpURLConnection connection = null;  
+        try {
+            url = new URL(request);
+            connection = (HttpURLConnection)url.openConnection();
+            connection.setRequestMethod("GET"); //$NON-NLS-1$
+            connection.setUseCaches(false);
+            connection.setDoInput(true);
+            
+            // pass in username / password
+            String encoded = Base64.getEncoder().encodeToString((USERNAME+":"+PASSWORD).getBytes()); //$NON-NLS-1$
+            connection.setRequestProperty("Authorization", "Basic "+encoded); //$NON-NLS-1$ //$NON-NLS-2$
+            connection.setRequestProperty("Accept-Charset", CHARSET);  //$NON-NLS-1$
+            
+            return consumer.apply(connection.getInputStream());
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+        
+        return null;
+    }
+    
+    private boolean filterOutIncompleteTranslations(String languageCode) {
+        // filter out any translation that does not have 100% completion and reviewed state.
+        // Returns a Map, for example:
+        // { 
+        //     untranslated_entities=8, 
+        //     last_commiter=eryzhikov, 
+        //     translated_entities=34, 
+        //     untranslated_words=16, 
+        //     translated_words=57, 
+        //     last_update=2014-09-12 08:44:33, 
+        //     reviewed_percentage=69%, 
+        //     reviewed=29, 
+        //     completed=80%
+        // }
+        Map<String, String> map = JSON.parse(transifexRequest(TRANSLATION_STATS, languageCode));
+        String completed = map.getOrDefault("completed", "0%"); //$NON-NLS-1$ //$NON-NLS-2$
+        String reviewed = map.getOrDefault("reviewed_percentage", "0%"); //$NON-NLS-1$ //$NON-NLS-2$
+        boolean isAccepted = completed.equals("100%") && reviewed.equals("100%"); //$NON-NLS-1$ //$NON-NLS-2$
+        
+        System.out.println("  Reviewing translation '" + languageCode + "'" +  //$NON-NLS-1$ //$NON-NLS-2$
+                "\tcompletion: " + completed +  //$NON-NLS-1$
+                ",\treviewed: " + reviewed +  //$NON-NLS-1$
+                "\t-> TRANSLATION" + (isAccepted ? " ACCEPTED" : " REJECTED")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        
+        return isAccepted || !FILTER_INCOMPLETE_TRANSLATIONS;
+    }
+    
+    private void downloadTranslation(String languageCode) {
+        // Now we download the translations of the completed languages
+        System.out.println("\tDownloading translation file..."); //$NON-NLS-1$
+        
+        Function<InputStream, Void> consumer = inputStream -> {
+            final String outputFile = "build/resources/main/" + String.format(FILE_NAME, languageCode); //$NON-NLS-1$
+            
+            ReadableByteChannel rbc = Channels.newChannel(inputStream);
+            try (FileOutputStream fos = new FileOutputStream(outputFile)) {
+                fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return null;
+        };
+        performTransifexTask(consumer, GET_TRANSLATION, languageCode);
+    }
+}
diff --git a/src/impl/org/controlsfx/ImplUtils.java b/src/impl/org/controlsfx/ImplUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..08bbbee58409eca5fc3d74c3ede75216074ff48b
--- /dev/null
+++ b/src/impl/org/controlsfx/ImplUtils.java
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Control;
+import javafx.scene.control.Skin;
+import javafx.scene.control.SkinBase;
+import javafx.scene.layout.Pane;
+
+public class ImplUtils {
+
+    private ImplUtils() {
+        // no-op
+    }
+    
+    public static void injectAsRootPane(Scene scene, Parent injectedParent, boolean useReflection) {
+        Parent originalParent = scene.getRoot();
+        scene.setRoot(injectedParent);
+        
+        if (originalParent != null) {
+            getChildren(injectedParent, useReflection).add(0, originalParent);
+            
+            // copy in layout properties, etc, so that the dialogStack displays
+            // properly in (hopefully) whatever layout the owner node is in
+            injectedParent.getProperties().putAll(originalParent.getProperties());
+        }
+    }
+    
+    // parent is where we want to inject the injectedParent. We then need to
+    // set the child of the injectedParent to include parent.
+    // The end result is that we've forced in the injectedParent node above parent.
+    public static void injectPane(Parent parent, Parent injectedParent, boolean useReflection) {
+        if (parent == null) {
+            throw new IllegalArgumentException("parent can not be null"); //$NON-NLS-1$
+        }
+        
+        List<Node> ownerParentChildren = getChildren(parent.getParent(), useReflection);
+        
+        // we've got the children list, now we need to insert a temporary
+        // layout container holding our dialogs and opaque layer / effect
+        // in place of the owner (the owner will become a child of the dialog
+        // stack)
+        int ownerPos = ownerParentChildren.indexOf(parent);
+        ownerParentChildren.remove(ownerPos);
+        ownerParentChildren.add(ownerPos, injectedParent);
+        
+        // now we install the parent as a child of the injectedParent
+        getChildren(injectedParent, useReflection).add(0, parent);
+        
+        // copy in layout properties, etc, so that the dialogStack displays
+        // properly in (hopefully) whatever layout the owner node is in
+        injectedParent.getProperties().putAll(parent.getProperties());
+    }
+    
+    public static void stripRootPane(Scene scene, Parent originalParent, boolean useReflection) {
+        Parent oldParent = scene.getRoot();
+        getChildren(oldParent, useReflection).remove(originalParent);
+        originalParent.getStyleClass().remove("root"); //$NON-NLS-1$
+        scene.setRoot(originalParent);        
+    }
+    
+    public static List<Node> getChildren(Node n, boolean useReflection) {
+        return n instanceof Parent ? getChildren((Parent)n, useReflection) : Collections.emptyList();
+    }
+    
+    public static List<Node> getChildren(Parent p, boolean useReflection) {
+        ObservableList<Node> children = null;
+        
+        // previously we used reflection immediately, now we try to avoid reflection
+        // by checking the type of the Parent. Still not great...
+        if (p instanceof Pane) {
+            // This should cover the majority of layout containers, including
+            // AnchorPane, FlowPane, GridPane, HBox, Pane, StackPane, TilePane, VBox
+            children = ((Pane)p).getChildren();
+        } else if (p instanceof Group) {
+            children = ((Group)p).getChildren();
+        } else if (p instanceof Control) {
+            Control c = (Control) p;
+            Skin<?> s = c.getSkin();
+            children = s instanceof SkinBase ? ((SkinBase<?>)s).getChildren() : getChildrenReflectively(p);
+        } else if (useReflection) {
+            // we really want to avoid using this!!!!
+            children = getChildrenReflectively(p);
+        }
+        
+        if (children == null) {
+            throw new RuntimeException("Unable to get children for Parent of type " + p.getClass() +  //$NON-NLS-1$
+                                       ". useReflection is set to " + useReflection); //$NON-NLS-1$
+        }
+        
+        return children == null ? FXCollections.emptyObservableList() : children;
+    }
+    
+    @SuppressWarnings("unchecked")
+	public static ObservableList<Node> getChildrenReflectively(Parent p) {
+        ObservableList<Node> children = null;
+        
+        try {
+            Method getChildrenMethod = Parent.class.getDeclaredMethod("getChildren"); //$NON-NLS-1$
+            
+            if (getChildrenMethod != null) {
+                if (! getChildrenMethod.isAccessible()) {
+                    getChildrenMethod.setAccessible(true);
+                }
+                children = (ObservableList<Node>) getChildrenMethod.invoke(p);
+            } else {
+                // uh oh, trouble
+            }
+        } catch (ReflectiveOperationException | IllegalArgumentException e) {
+            throw new RuntimeException("Unable to get children for Parent of type " + p.getClass(), e); //$NON-NLS-1$
+        }
+        
+        return children;
+    }
+}
diff --git a/src/impl/org/controlsfx/autocompletion/AutoCompletionTextFieldBinding.java b/src/impl/org/controlsfx/autocompletion/AutoCompletionTextFieldBinding.java
new file mode 100644
index 0000000000000000000000000000000000000000..67416a6ce12d9ec1d78c00be84b2d2db912eda32
--- /dev/null
+++ b/src/impl/org/controlsfx/autocompletion/AutoCompletionTextFieldBinding.java
@@ -0,0 +1,161 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.autocompletion;
+
+import java.util.Collection;
+
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.TextField;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+
+import org.controlsfx.control.textfield.AutoCompletionBinding;
+
+/**
+ * Represents a binding between a text field and a auto-completion popup
+ *
+ * @param <T>
+ */
+public class AutoCompletionTextFieldBinding<T>  extends AutoCompletionBinding<T>{
+
+    /***************************************************************************
+     *                                                                         *
+     * Static properties and methods                                           *
+     *                                                                         *
+     **************************************************************************/
+    
+    private static <T> StringConverter<T> defaultStringConverter() {
+        return new StringConverter<T>() {
+            @Override public String toString(T t) {
+                return t == null ? null : t.toString();
+            }
+            @SuppressWarnings("unchecked")
+			@Override public T fromString(String string) {
+                return (T) string;
+            }
+        };
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Private fields                                                          *
+     *                                                                         *
+     **************************************************************************/
+	
+    /**
+     * String converter to be used to convert suggestions to strings.
+     */
+	private StringConverter<T> converter;
+
+	
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Creates a new auto-completion binding between the given textField 
+     * and the given suggestion provider.
+     * 
+     * @param textField
+     * @param suggestionProvider
+     */
+    public AutoCompletionTextFieldBinding(final TextField textField,
+            Callback<ISuggestionRequest, Collection<T>> suggestionProvider) {
+    	
+        this(textField, suggestionProvider, AutoCompletionTextFieldBinding
+    			.<T>defaultStringConverter());
+    }
+
+    /**
+     * Creates a new auto-completion binding between the given textField 
+     * and the given suggestion provider.
+     * 
+     * @param textField
+     * @param suggestionProvider
+     */
+    public AutoCompletionTextFieldBinding(final TextField textField,
+            Callback<ISuggestionRequest, Collection<T>> suggestionProvider,
+            final StringConverter<T> converter) {
+    	
+        super(textField, suggestionProvider, converter);
+        this.converter = converter; 
+
+        getCompletionTarget().textProperty().addListener(textChangeListener);
+        getCompletionTarget().focusedProperty().addListener(focusChangedListener);
+    }
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /** {@inheritDoc} */
+    @Override public TextField getCompletionTarget(){
+        return (TextField)super.getCompletionTarget();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void dispose(){
+        getCompletionTarget().textProperty().removeListener(textChangeListener);
+        getCompletionTarget().focusedProperty().removeListener(focusChangedListener);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void completeUserInput(T completion){
+    	String newText = converter.toString(completion);     	
+        getCompletionTarget().setText(newText);
+        getCompletionTarget().positionCaret(newText.length());
+    }
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Event Listeners                                                         *
+     *                                                                         *
+     **************************************************************************/
+
+
+    private final ChangeListener<String> textChangeListener = new ChangeListener<String>() {
+        @Override public void changed(ObservableValue<? extends String> obs, String oldText, String newText) {
+            if (getCompletionTarget().isFocused()) {
+                setUserInput(newText);
+            }
+        }
+    };
+
+    private final ChangeListener<Boolean> focusChangedListener = new ChangeListener<Boolean>() {
+        @Override public void changed(ObservableValue<? extends Boolean> obs, Boolean oldFocused, Boolean newFocused) {
+            if(newFocused == false)
+                hidePopup();
+        }
+    };
+}
diff --git a/src/impl/org/controlsfx/autocompletion/SuggestionProvider.java b/src/impl/org/controlsfx/autocompletion/SuggestionProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c178033db807e2da84c2226d703a98baf29ce52
--- /dev/null
+++ b/src/impl/org/controlsfx/autocompletion/SuggestionProvider.java
@@ -0,0 +1,199 @@
+/**
+ * Copyright (c) 2014, 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.autocompletion;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javafx.util.Callback;
+
+import org.controlsfx.control.textfield.AutoCompletionBinding.ISuggestionRequest;
+
+/**
+ * This is a simple implementation of a generic suggestion provider callback.
+ * The complexity of suggestion generation is O(n) where n is the number of possible suggestions.
+ * 
+ * @param <T> Type of suggestions
+ */
+public abstract class SuggestionProvider<T> implements Callback<ISuggestionRequest, Collection<T>>{
+
+    private final List<T> possibleSuggestions = new ArrayList<>();
+    private final Object possibleSuggestionsLock = new Object();
+
+
+    /**
+     * Add the given new possible suggestions to this  SuggestionProvider
+     * @param newPossible
+     */
+    public void addPossibleSuggestions(@SuppressWarnings("unchecked") T... newPossible){     
+        addPossibleSuggestions(Arrays.asList(newPossible));
+    }
+
+    /**
+     * Add the given new possible suggestions to this  SuggestionProvider
+     * @param newPossible
+     */
+    public void addPossibleSuggestions(Collection<T> newPossible){
+        synchronized (possibleSuggestionsLock) {
+            possibleSuggestions.addAll(newPossible);
+        }
+    }
+
+    /**
+     * Remove all current possible suggestions
+     */
+    public void clearSuggestions(){
+        synchronized (possibleSuggestionsLock) {
+            possibleSuggestions.clear();
+        }
+    }
+
+    @Override
+    public final Collection<T> call(final ISuggestionRequest request) {
+        List<T> suggestions = new ArrayList<>();
+        if(!request.getUserText().isEmpty()){
+            synchronized (possibleSuggestionsLock) {
+                for (T possibleSuggestion : possibleSuggestions) {
+                    if(isMatch(possibleSuggestion, request)){
+                        suggestions.add(possibleSuggestion);
+                    }
+                }
+            }
+            Collections.sort(suggestions, getComparator());
+        }
+        return suggestions;
+    }
+
+    /**
+     * Get the comparator to order the suggestions
+     * @return
+     */
+    protected abstract Comparator<T> getComparator();
+
+    /**
+     * Check the given possible suggestion is a match (is a valid suggestion)
+     * @param suggestion
+     * @param request
+     * @return
+     */
+    protected abstract boolean isMatch(T suggestion, ISuggestionRequest request);
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Static methods                                                          *
+     *                                                                         *
+     **************************************************************************/
+
+
+    /**
+     * Create a default suggestion provider based on the toString() method of the generic objects
+     * @param possibleSuggestions All possible suggestions
+     * @return
+     */
+    public static <T> SuggestionProvider<T> create(Collection<T> possibleSuggestions){
+        return create(null, possibleSuggestions);
+    }
+
+    /**
+     * Create a default suggestion provider based on the toString() method of the generic objects
+     * using the provided stringConverter
+     * 
+     * @param stringConverter A stringConverter which converts generic T into a string
+     * @param possibleSuggestions All possible suggestions
+     * @return
+     */
+    public static <T> SuggestionProvider<T> create(Callback<T, String> stringConverter, Collection<T> possibleSuggestions){
+        SuggestionProviderString<T> suggestionProvider = new SuggestionProviderString<>(stringConverter);
+        suggestionProvider.addPossibleSuggestions(possibleSuggestions);
+        return suggestionProvider;
+    }
+
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Default implementations                                                 *
+     *                                                                         *
+     **************************************************************************/
+
+
+    /**
+     * This is a simple string based suggestion provider.
+     * All generic suggestions T are turned into strings for processing.
+     * 
+     */
+    private static class SuggestionProviderString<T> extends SuggestionProvider<T> {
+
+        private Callback<T, String> stringConverter;
+
+        private final Comparator<T> stringComparator = new Comparator<T>() {
+            @Override
+            public int compare(T o1, T o2) {
+                String o1str = stringConverter.call(o1);
+                String o2str = stringConverter.call(o2);
+                return o1str.compareTo(o2str);
+            }
+        };
+
+        /**
+         * Create a new SuggestionProviderString
+         * @param stringConverter
+         */
+        public SuggestionProviderString(Callback<T, String> stringConverter){
+            this.stringConverter = stringConverter;
+
+            // In case no stringConverter was provided, use the default strategy
+            if(this.stringConverter == null){
+                this.stringConverter = new Callback<T, String>() {
+                    @Override
+                    public String call(T obj) {
+                        return obj != null ? obj.toString() : ""; //$NON-NLS-1$
+                    }
+                };
+            }
+        }
+
+        /**{@inheritDoc}*/
+        @Override
+        protected Comparator<T> getComparator() {
+            return stringComparator;
+        }
+
+        /**{@inheritDoc}*/
+        @Override
+        protected boolean isMatch(T suggestion, ISuggestionRequest request) {
+            String userTextLower = request.getUserText().toLowerCase();
+            String suggestionStr = suggestion.toString().toLowerCase();
+            return suggestionStr.contains(userTextLower);
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/behavior/RangeSliderBehavior.java b/src/impl/org/controlsfx/behavior/RangeSliderBehavior.java
new file mode 100644
index 0000000000000000000000000000000000000000..e0f16653bfaf1b0b53b7e1ccc806b12cec6c20a9
--- /dev/null
+++ b/src/impl/org/controlsfx/behavior/RangeSliderBehavior.java
@@ -0,0 +1,339 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.behavior;
+
+import static javafx.scene.input.KeyCode.DOWN;
+import static javafx.scene.input.KeyCode.END;
+import static javafx.scene.input.KeyCode.F4;
+import static javafx.scene.input.KeyCode.HOME;
+import static javafx.scene.input.KeyCode.KP_DOWN;
+import static javafx.scene.input.KeyCode.KP_LEFT;
+import static javafx.scene.input.KeyCode.KP_RIGHT;
+import static javafx.scene.input.KeyCode.KP_UP;
+import static javafx.scene.input.KeyCode.LEFT;
+import static javafx.scene.input.KeyCode.RIGHT;
+import static javafx.scene.input.KeyCode.UP;
+import static javafx.scene.input.KeyEvent.KEY_RELEASED;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javafx.event.EventType;
+import javafx.geometry.Orientation;
+import javafx.scene.control.Control;
+import javafx.scene.control.Skin;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.util.Callback;
+
+import org.controlsfx.control.RangeSlider;
+import org.controlsfx.tools.Utils;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.behavior.OrientedKeyBinding;
+
+public class RangeSliderBehavior extends BehaviorBase<RangeSlider> {
+    
+     /**************************************************************************
+     *                          Setup KeyBindings                             *
+     *                                                                        *
+     * We manually specify the focus traversal keys because Slider has        *
+     * different usage for up/down arrow keys.                                *
+     *************************************************************************/
+    private static final List<KeyBinding> RANGESLIDER_BINDINGS = new ArrayList<>();
+    static {
+        RANGESLIDER_BINDINGS.add(new KeyBinding(F4, "TraverseDebug").alt().ctrl().shift()); //$NON-NLS-1$
+
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(LEFT, "DecrementValue")); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(KP_LEFT, "DecrementValue")); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(UP, "IncrementValue").vertical()); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(KP_UP, "IncrementValue").vertical()); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(RIGHT, "IncrementValue")); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(KP_RIGHT, "IncrementValue")); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(DOWN, "DecrementValue").vertical()); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(KP_DOWN, "DecrementValue").vertical()); //$NON-NLS-1$
+
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(LEFT, "TraverseLeft").vertical()); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(KP_LEFT, "TraverseLeft").vertical()); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(UP, "TraverseUp")); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(KP_UP, "TraverseUp")); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(RIGHT, "TraverseRight").vertical()); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(KP_RIGHT, "TraverseRight").vertical()); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(DOWN, "TraverseDown")); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new RangeSliderKeyBinding(KP_DOWN, "TraverseDown")); //$NON-NLS-1$
+
+        RANGESLIDER_BINDINGS.add(new KeyBinding(HOME, KEY_RELEASED, "Home")); //$NON-NLS-1$
+        RANGESLIDER_BINDINGS.add(new KeyBinding(END, KEY_RELEASED, "End")); //$NON-NLS-1$
+    }
+    
+    public RangeSliderBehavior(RangeSlider slider) {
+        super(slider, RANGESLIDER_BINDINGS);
+    }
+
+    @Override protected void callAction(String s) {
+        if ("Home".equals(s) || "Home2".equals(s)) home(); //$NON-NLS-1$ //$NON-NLS-2$
+        else if ("End".equals(s) || "End2".equals(s)) end(); //$NON-NLS-1$ //$NON-NLS-2$
+        else if ("IncrementValue".equals(s) || "IncrementValue2".equals(s)) incrementValue(); //$NON-NLS-1$ //$NON-NLS-2$
+        else if ("DecrementValue".equals(s) || "DecrementValue2".equals(s)) decrementValue(); //$NON-NLS-1$ //$NON-NLS-2$
+        else super.callAction(s);
+    }
+     
+    /**************************************************************************
+     *                         State and Functions                            *
+     *************************************************************************/
+
+    private Callback<Void, FocusedChild> selectedValue;
+    public void setSelectedValue(Callback<Void, FocusedChild> c) {
+        selectedValue = c;
+    }
+    /**
+     * Invoked by the RangeSlider {@link Skin} implementation whenever a mouse press
+     * occurs on the "track" of the slider. This will cause the thumb to be
+     * moved by some amount.
+     *
+     * @param position The mouse position on track with 0.0 being beginning of
+     *        track and 1.0 being the end
+     */
+    public void trackPress(MouseEvent e, double position) {
+        // determine the percentage of the way between min and max
+        // represented by this mouse event
+        final RangeSlider rangeSlider = getControl();
+        // If not already focused, request focus
+        if (!rangeSlider.isFocused()) {
+            rangeSlider.requestFocus();
+        }
+        if (selectedValue != null) {
+            double newPosition;
+            if (rangeSlider.getOrientation().equals(Orientation.HORIZONTAL)) {
+                newPosition = position * (rangeSlider.getMax() - rangeSlider.getMin()) + rangeSlider.getMin();
+            } else {
+                newPosition = (1 - position) * (rangeSlider.getMax() - rangeSlider.getMin()) + rangeSlider.getMin();
+            }
+
+            /**
+             * If the position is inferior to the current LowValue, this means
+             * the user clicked on the track to move the low thumb. If not, then
+             * it means the user wanted to move the high thumb.
+             */
+            if (newPosition < rangeSlider.getLowValue()) {
+                rangeSlider.adjustLowValue(newPosition);
+            } else {
+                rangeSlider.adjustHighValue(newPosition);
+            }
+        }
+    }
+
+    /**
+     */
+    public void trackRelease(MouseEvent e, double position) {
+    }
+    
+     /**
+     * @param position The mouse position on track with 0.0 being beginning of
+      *       track and 1.0 being the end
+     */
+    public void lowThumbPressed(MouseEvent e, double position) {
+        // If not already focused, request focus
+        final RangeSlider rangeSlider = getControl();
+        if (!rangeSlider.isFocused())  rangeSlider.requestFocus();
+        rangeSlider.setLowValueChanging(true);
+    }
+
+    /**
+     * @param position The mouse position on track with 0.0 being beginning of
+     *        track and 1.0 being the end
+     */
+    public void lowThumbDragged(MouseEvent e, double position) {
+        final RangeSlider rangeSlider = getControl();
+        double newValue = Utils.clamp(rangeSlider.getMin(), 
+                (position * (rangeSlider.getMax() - rangeSlider.getMin())) + rangeSlider.getMin(), 
+                rangeSlider.getMax());
+        rangeSlider.setLowValue(newValue);
+    }
+    
+    /**
+     * When lowThumb is released lowValueChanging should be set to false.
+     */
+    public void lowThumbReleased(MouseEvent e) {
+        final RangeSlider rangeSlider = getControl();
+        rangeSlider.setLowValueChanging(false);
+        // RT-15207 When snapToTicks is true, slider value calculated in drag
+        // is then snapped to the nearest tick on mouse release.
+        if (rangeSlider.isSnapToTicks()) {
+            rangeSlider.setLowValue(snapValueToTicks(rangeSlider.getLowValue()));
+        }
+    }
+    
+    void home() {
+        RangeSlider slider = (RangeSlider) getControl();
+        slider.adjustHighValue(slider.getMin());
+    }
+
+    void decrementValue() {
+        RangeSlider slider = (RangeSlider) getControl();
+        if (selectedValue != null) {
+            if (selectedValue.call(null) == FocusedChild.HIGH_THUMB) {
+                if (slider.isSnapToTicks())
+                    slider.adjustHighValue(slider.getHighValue() - computeIncrement());
+                else
+                    slider.decrementHighValue();
+            } else {
+                if (slider.isSnapToTicks())
+                    slider.adjustLowValue(slider.getLowValue() - computeIncrement());
+                else
+                    slider.decrementLowValue();
+            }
+        }
+    }
+
+    void end() {
+        RangeSlider slider = (RangeSlider) getControl();
+        slider.adjustHighValue(slider.getMax());
+    }
+
+    void incrementValue() {
+        RangeSlider slider = (RangeSlider) getControl();
+        if (selectedValue != null) {
+            if (selectedValue.call(null) == FocusedChild.HIGH_THUMB) {
+                if (slider.isSnapToTicks())
+                    slider.adjustHighValue(slider.getHighValue() + computeIncrement());
+                else
+                    slider.incrementHighValue();
+            } else {
+                if (slider.isSnapToTicks())
+                    slider.adjustLowValue(slider.getLowValue() + computeIncrement());
+                else
+                    slider.incrementLowValue();
+            }
+        }
+        
+    }
+
+    double computeIncrement() {
+        RangeSlider rangeSlider = (RangeSlider) getControl();
+        double d = 0.0D;
+        if (rangeSlider.getMinorTickCount() != 0)
+            d = rangeSlider.getMajorTickUnit() / (double) (Math.max(rangeSlider.getMinorTickCount(), 0) + 1);
+        else
+            d = rangeSlider.getMajorTickUnit();
+        if (rangeSlider.getBlockIncrement() > 0.0D && rangeSlider.getBlockIncrement() < d)
+            return d;
+        else
+            return rangeSlider.getBlockIncrement();
+    }
+
+    private double snapValueToTicks(double d) {
+        RangeSlider rangeSlider = (RangeSlider) getControl();
+        double d1 = d;
+        double d2 = 0.0D;
+        if (rangeSlider.getMinorTickCount() != 0)
+            d2 = rangeSlider.getMajorTickUnit() / (double) (Math.max(rangeSlider.getMinorTickCount(), 0) + 1);
+        else
+            d2 = rangeSlider.getMajorTickUnit();
+        int i = (int) ((d1 - rangeSlider.getMin()) / d2);
+        double d3 = (double) i * d2 + rangeSlider.getMin();
+        double d4 = (double) (i + 1) * d2 + rangeSlider.getMin();
+        d1 = Utils.nearest(d3, d1, d4);
+        return Utils.clamp(rangeSlider.getMin(), d1, rangeSlider.getMax());
+    }
+
+    // when high thumb is released, highValueChanging is set to false.
+    public void highThumbReleased(MouseEvent e) {
+        RangeSlider slider = (RangeSlider) getControl();
+        slider.setHighValueChanging(false);
+        if (slider.isSnapToTicks())
+            slider.setHighValue(snapValueToTicks(slider.getHighValue()));
+    }
+
+    public void highThumbPressed(MouseEvent e, double position) {
+        RangeSlider slider = (RangeSlider) getControl();
+        if (!slider.isFocused())
+            slider.requestFocus();
+        slider.setHighValueChanging(true);
+    }
+
+    public void highThumbDragged(MouseEvent e, double position) {
+        RangeSlider slider = (RangeSlider) getControl();
+        slider.setHighValue(Utils.clamp(slider.getMin(), position * (slider.getMax() - slider.getMin()) + slider.getMin(), slider.getMax()));
+    }
+    
+    public void moveRange(double position) {
+        RangeSlider slider = (RangeSlider) getControl();
+        final double min = slider.getMin();
+        final double max = slider.getMax();
+        final double lowValue = slider.getLowValue();
+        final double newLowValue = Utils.clamp(min, lowValue + position *(max-min) / 
+                (slider.getOrientation() == Orientation.HORIZONTAL? slider.getWidth(): slider.getHeight()), max);
+        final double highValue = slider.getHighValue();
+        final double newHighValue = Utils.clamp(min, highValue + position*(max-min) / 
+                (slider.getOrientation() == Orientation.HORIZONTAL? slider.getWidth(): slider.getHeight()), max);
+        
+        if (newLowValue <= min || newHighValue >= max) return;
+        slider.setLowValueChanging(true);
+        slider.setHighValueChanging(true);
+        slider.setLowValue(newLowValue);
+        slider.setHighValue(newHighValue);        
+    }
+    
+      public void confirmRange() {
+        RangeSlider slider = (RangeSlider) getControl();
+
+        slider.setLowValueChanging(false);
+        if (slider.isSnapToTicks()) {
+            slider.setLowValue(snapValueToTicks(slider.getLowValue()));
+        }
+        slider.setHighValueChanging(false);
+        if (slider.isSnapToTicks()) {
+            slider.setHighValue(snapValueToTicks(slider.getHighValue()));
+        }
+
+    }
+    
+    public static class RangeSliderKeyBinding extends OrientedKeyBinding {
+        public RangeSliderKeyBinding(KeyCode code, String action) {
+            super(code, action);
+        }
+
+        public RangeSliderKeyBinding(KeyCode code, EventType<KeyEvent> type, String action) {
+            super(code, type, action);
+        }
+
+        public @Override boolean getVertical(Control control) {
+            return ((RangeSlider)control).getOrientation() == Orientation.VERTICAL;
+        }
+    }
+     
+    public enum FocusedChild {
+        LOW_THUMB,
+        HIGH_THUMB,
+        RANGE_BAR,
+        NONE
+    }
+}
+
diff --git a/src/impl/org/controlsfx/behavior/RatingBehavior.java b/src/impl/org/controlsfx/behavior/RatingBehavior.java
new file mode 100644
index 0000000000000000000000000000000000000000..284d299f8ca0e1d814ed02fe4dbb9bd41c1a9fa5
--- /dev/null
+++ b/src/impl/org/controlsfx/behavior/RatingBehavior.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.behavior;
+
+import java.util.Collections;
+
+import org.controlsfx.control.Rating;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+
+public class RatingBehavior extends BehaviorBase<Rating> {
+
+    public RatingBehavior(Rating control) {
+        super(control, Collections.<KeyBinding> emptyList());
+    }
+}
\ No newline at end of file
diff --git a/src/impl/org/controlsfx/behavior/SnapshotViewBehavior.java b/src/impl/org/controlsfx/behavior/SnapshotViewBehavior.java
new file mode 100644
index 0000000000000000000000000000000000000000..33456ec991c3e1e2b568281de95dbe2ede894a63
--- /dev/null
+++ b/src/impl/org/controlsfx/behavior/SnapshotViewBehavior.java
@@ -0,0 +1,783 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.behavior;
+
+import impl.org.controlsfx.tools.rectangle.CoordinatePosition;
+import impl.org.controlsfx.tools.rectangle.CoordinatePositions;
+import impl.org.controlsfx.tools.rectangle.Rectangles2D;
+import impl.org.controlsfx.tools.rectangle.change.MoveChangeStrategy;
+import impl.org.controlsfx.tools.rectangle.change.NewChangeStrategy;
+import impl.org.controlsfx.tools.rectangle.change.Rectangle2DChangeStrategy;
+import impl.org.controlsfx.tools.rectangle.change.ToEastChangeStrategy;
+import impl.org.controlsfx.tools.rectangle.change.ToNorthChangeStrategy;
+import impl.org.controlsfx.tools.rectangle.change.ToNortheastChangeStrategy;
+import impl.org.controlsfx.tools.rectangle.change.ToNorthwestChangeStrategy;
+import impl.org.controlsfx.tools.rectangle.change.ToSouthChangeStrategy;
+import impl.org.controlsfx.tools.rectangle.change.ToSoutheastChangeStrategy;
+import impl.org.controlsfx.tools.rectangle.change.ToSouthwestChangeStrategy;
+import impl.org.controlsfx.tools.rectangle.change.ToWestChangeStrategy;
+
+import java.util.ArrayList;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+import javafx.event.EventType;
+import javafx.geometry.Bounds;
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+import javafx.scene.Cursor;
+import javafx.scene.Node;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+
+import org.controlsfx.control.SnapshotView;
+import org.controlsfx.control.SnapshotView.Boundary;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+
+/**
+ * The behavior for the {@link SnapshotView}. It is concerned with creating and changing selections according to mouse
+ * events handed to {@link #handleMouseEvent(MouseEvent) handleMouseEvents}.
+ */
+public class SnapshotViewBehavior extends BehaviorBase<SnapshotView> {
+
+    /**
+     * The percentage of the control's node's width/height used as a tolerance for determining whether the cursor is on
+     * an edge of the selection.
+     */
+    private static final double RELATIVE_EDGE_TOLERANCE = 0.015;
+
+    /* ************************************************************************
+     *                                                                         *
+     * Attributes                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * The current selection change; might be {@code null}.
+     */
+    private SelectionChange selectionChange;
+
+    /**
+     * A function which sets the {@link SnapshotView#selectionChangingProperty() selectionChanging} property to the
+     * given value.
+     */
+    private final Consumer<Boolean> setSelectionChanging;
+
+    /* ************************************************************************
+     *                                                                         *
+     * Constructor                                                             *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Creates a new behavior for the specified {@link SnapshotView}.
+     * 
+     * @param snapshotView
+     *            the control which this behavior will control
+     */
+    public SnapshotViewBehavior(SnapshotView snapshotView) {
+        super(snapshotView, new ArrayList<KeyBinding>());
+        this.setSelectionChanging = createSetSelectionChanging();
+    }
+
+    /**
+     * Creates a function which sets the applied boolean to {@link SnapshotView#selectionChangingProperty()}.
+     * 
+     * @return a Boolean {@link Consumer}
+     */
+    private Consumer<Boolean> createSetSelectionChanging() {
+        return changing -> getControl().getProperties().put(SnapshotView.SELECTION_CHANGING_PROPERTY_KEY, changing);
+    }
+
+    /* ************************************************************************
+     *                                                                         *
+     * Events                                                                  *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Handles the specified mouse event (possibly by creating/changing/removing a selection) and returns the matching
+     * cursor.
+     * 
+     * @param mouseEvent
+     *            the handled {@link MouseEvent}; must not be {@code null}
+     * @return the cursor which will be used for this event
+     */
+    public Cursor handleMouseEvent(MouseEvent mouseEvent) {
+        Objects.requireNonNull(mouseEvent, "The argument 'mouseEvent' must not be null."); //$NON-NLS-1$
+
+        EventType<? extends MouseEvent> eventType = mouseEvent.getEventType();
+        SelectionEvent selectionEvent = createSelectionEvent(mouseEvent);
+
+        if (eventType == MouseEvent.MOUSE_MOVED) {
+            return getCursor(selectionEvent);
+        }
+        if (eventType == MouseEvent.MOUSE_PRESSED) {
+            return handleMousePressedEvent(selectionEvent);
+        }
+        if (eventType == MouseEvent.MOUSE_DRAGGED) {
+            return handleMouseDraggedEvent(selectionEvent);
+        }
+        if (eventType == MouseEvent.MOUSE_RELEASED) {
+            return handleMouseReleasedEvent(selectionEvent);
+        }
+
+        return Cursor.DEFAULT;
+    }
+
+    // TRANSFORM MOUSE EVENT TO SELECTION EVENT
+
+    /**
+     * Creates a selection event for the specified mouse event
+     * 
+     * @param mouseEvent
+     *            the {@link MouseEvent} for which the selection event will be created
+     * @return the {@link SelectionEvent} for the specified mouse event
+     */
+    private SelectionEvent createSelectionEvent(MouseEvent mouseEvent) {
+        Point2D point = new Point2D(mouseEvent.getX(), mouseEvent.getY());
+        Rectangle2D selectionBounds = createBoundsForCurrentBoundary();
+        CoordinatePosition position = computePosition(point);
+        return new SelectionEvent(mouseEvent, point, selectionBounds, position);
+    }
+
+    /**
+     * Returns the bounds according to the current {@link SnapshotView#selectionAreaBoundaryProperty()
+     * selectionAreaBoundary}.
+     * 
+     * @return the bounds as a {@link Rectangle2D}
+     */
+    private Rectangle2D createBoundsForCurrentBoundary() {
+        Boundary boundary = getControl().getSelectionAreaBoundary();
+        switch (boundary) {
+        case CONTROL:
+            return new Rectangle2D(0, 0, getControlWidth(), getControlHeight());
+        case NODE:
+            boolean nodeExists = getNode() != null;
+            if (nodeExists) {
+                Bounds nodeBounds = getNode().getBoundsInParent();
+                return Rectangles2D.fromBounds(nodeBounds);
+            } else {
+                return Rectangle2D.EMPTY;
+            }
+        default:
+            throw new IllegalArgumentException("The boundary " + boundary + " is not fully implemented."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+    }
+
+    /**
+     * Returns the position of the specified point relative to a possible selection.
+     * 
+     * @param point
+     *            the point (in the node's preferred coordinates) whose position will be computed
+     * 
+     * @return the {@link CoordinatePosition} the event's point has relative to the control's current selection; if the
+     *         selection is inactive this always returns {@link CoordinatePosition#OUT_OF_RECTANGLE}.
+     */
+    private CoordinatePosition computePosition(Point2D point) {
+        boolean noSelection = !getControl().hasSelection() || !getControl().isSelectionActive();
+        boolean controlHasNoSpace = getControlWidth() == 0 || getControlHeight() == 0;
+        if (noSelection || controlHasNoSpace) {
+            return CoordinatePosition.OUT_OF_RECTANGLE;
+        }
+
+        double tolerance = computeTolerance();
+        return computePosition(getSelection(), point, tolerance);
+    }
+
+    /**
+     * Computes the tolerance which is used to determine whether the cursor is on an edge.
+     * 
+     * @return the absolute tolerance
+     */
+    private double computeTolerance() {
+        double controlMeanLength = Math.sqrt(getControlWidth() * getControlHeight());
+        return RELATIVE_EDGE_TOLERANCE * controlMeanLength;
+    }
+
+    /**
+     * Returns the position of the specified point relative to the specified selection with the specified tolerance.
+     * 
+     * @param selection
+     *            the selection relative to which the point's position will be computed; as a {@link Rectangle2D}
+     * @param point
+     *            the {@link Point2D} whose position will be computed
+     * @param tolerance
+     *            the absolute tolerance used to determine whether the point is on an edge
+     * 
+     * @return the {@link CoordinatePosition} the event's point has relative to the control's current selection; if the
+     *         selection is inactive this always returns {@link CoordinatePosition#OUT_OF_RECTANGLE}.
+     */
+    private static CoordinatePosition computePosition(Rectangle2D selection, Point2D point, double tolerance) {
+        CoordinatePosition onEdge = CoordinatePositions.onEdges(selection, point, tolerance);
+        if (onEdge != null) {
+            return onEdge;
+        } else {
+            return CoordinatePositions.inRectangle(selection, point);
+        }
+    }
+
+    // HANDLE SELECTION EVENTS
+
+    /**
+     * Handles {@link MouseEvent#MOUSE_PRESSED} events by creating a new {@link #selectionChange} and beginning the
+     * change.
+     * 
+     * @param selectionEvent
+     *            the handled {@link SelectionEvent}
+     * @return the cursor which will be used while the selection changes
+     */
+    private Cursor handleMousePressedEvent(SelectionEvent selectionEvent) {
+        if (selectionEvent.isPointInSelectionBounds()) {
+            // get all necessary information to create a selection change
+            Cursor cursor = getCursor(selectionEvent);
+            Rectangle2DChangeStrategy selectionChangeStrategy = getChangeStrategy(selectionEvent);
+            boolean deactivateSelectionIfClick = willDeactivateSelectionIfClick(selectionEvent);
+
+            // create and begin the selection change
+            selectionChange = new SelectionChangeByStrategy(
+                    getControl(), setSelectionChanging, selectionChangeStrategy, cursor, deactivateSelectionIfClick);
+            selectionChange.beginSelectionChange(selectionEvent.getPoint());
+        } else {
+            // if the mouse is outside the legal bounds, the selection will not actually change
+            selectionChange = NoSelectionChange.INSTANCE;
+        }
+
+        return selectionChange.getCursor();
+    }
+    /**
+     * Handles {@link MouseEvent#MOUSE_DRAGGED} events by continuing the current {@link #selectionChange}.
+     * 
+     * @param selectionEvent
+     *            the handled {@link SelectionEvent}
+     * @return the cursor which will be used while the selection changes
+     */
+    private Cursor handleMouseDraggedEvent(SelectionEvent selectionEvent) {
+        selectionChange.continueSelectionChange(selectionEvent.getPoint());
+        return selectionChange.getCursor();
+    }
+
+    /**
+     * Handles {@link MouseEvent#MOUSE_RELEASED} events by ending the current {@link #selectionChange} and setting it to
+     * {@code null}.
+     * 
+     * @param selectionEvent
+     *            the handled {@link SelectionEvent}
+     * @return the cursor which will be used after the selection change ends
+     */
+    private Cursor handleMouseReleasedEvent(SelectionEvent selectionEvent) {
+        // end and deactivate the selection change
+        selectionChange.endSelectionChange(selectionEvent.getPoint());
+        selectionChange = null;
+
+        return getCursor(selectionEvent);
+    }
+
+    // CURSOR AND SELECTION CHANGE
+
+    /**
+     * Returns the cursor which will be used for the specified selection event.
+     * 
+     * @param selectionEvent
+     *            the {@link SelectionEvent} to check
+     * @return the {@link Cursor} which will be used for the event
+     */
+    private Cursor getCursor(SelectionEvent selectionEvent) {
+        // show the default cursor if the mouse is out of the selection bounds
+        if (!selectionEvent.isPointInSelectionBounds()) {
+            return getRegularCursor();
+        }
+
+        // otherwise pick a cursor from the relative position
+        switch (selectionEvent.getPosition()) {
+        case IN_RECTANGLE:
+            return Cursor.MOVE;
+        case OUT_OF_RECTANGLE:
+            return getRegularCursor();
+        case NORTH_EDGE:
+            return Cursor.N_RESIZE;
+        case NORTHEAST_EDGE:
+            return Cursor.NE_RESIZE;
+        case EAST_EDGE:
+            return Cursor.E_RESIZE;
+        case SOUTHEAST_EDGE:
+            return Cursor.SE_RESIZE;
+        case SOUTH_EDGE:
+            return Cursor.S_RESIZE;
+        case SOUTHWEST_EDGE:
+            return Cursor.SW_RESIZE;
+        case WEST_EDGE:
+            return Cursor.W_RESIZE;
+        case NORTHWEST_EDGE:
+            return Cursor.NW_RESIZE;
+        default:
+            throw new IllegalArgumentException("The position " + selectionEvent.getPosition() //$NON-NLS-1$
+                    + " is not fully implemented."); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * @return the cursor from the {@link #getControl() control's} current {@link SnapshotView#cursorProperty() cursor}
+     */
+    private Cursor getRegularCursor() {
+        return getControl().getCursor();
+    }
+
+    /**
+     * Returns the selection change strategy based on the specified selection event, which must be a
+     * {@link MouseEvent#MOUSE_PRESSED MOUSE_PRESSED} event.
+     * 
+     * @param selectionEvent
+     *            the {@link SelectionEvent} which will be checked
+     * @return the {@link Rectangle2DChangeStrategy} which will be executed based on the selection event
+     * @throws IllegalArgumentException
+     *             if {@link SelectionEvent#getMouseEvent()} is not of type {@link MouseEvent#MOUSE_PRESSED}.
+     */
+    private Rectangle2DChangeStrategy getChangeStrategy(SelectionEvent selectionEvent) {
+        boolean mousePressed = selectionEvent.getMouseEvent().getEventType() == MouseEvent.MOUSE_PRESSED;
+        if (!mousePressed) {
+            throw new IllegalArgumentException();
+        }
+
+        Rectangle2D selectionBounds = selectionEvent.getSelectionBounds();
+
+        switch (selectionEvent.getPosition()) {
+        case IN_RECTANGLE:
+            return new MoveChangeStrategy(getSelection(), selectionBounds);
+        case OUT_OF_RECTANGLE:
+            return new NewChangeStrategy(
+                    isSelectionRatioFixed(), getSelectionRatio(), selectionBounds);
+        case NORTH_EDGE:
+            return new ToNorthChangeStrategy(
+                    getSelection(), isSelectionRatioFixed(), getSelectionRatio(), selectionBounds);
+        case NORTHEAST_EDGE:
+            return new ToNortheastChangeStrategy(
+                    getSelection(), isSelectionRatioFixed(), getSelectionRatio(), selectionBounds);
+        case EAST_EDGE:
+            return new ToEastChangeStrategy(
+                    getSelection(), isSelectionRatioFixed(), getSelectionRatio(), selectionBounds);
+        case SOUTHEAST_EDGE:
+            return new ToSoutheastChangeStrategy(
+                    getSelection(), isSelectionRatioFixed(), getSelectionRatio(), selectionBounds);
+        case SOUTH_EDGE:
+            return new ToSouthChangeStrategy(
+                    getSelection(), isSelectionRatioFixed(), getSelectionRatio(), selectionBounds);
+        case SOUTHWEST_EDGE:
+            return new ToSouthwestChangeStrategy(
+                    getSelection(), isSelectionRatioFixed(), getSelectionRatio(), selectionBounds);
+        case WEST_EDGE:
+            return new ToWestChangeStrategy(
+                    getSelection(), isSelectionRatioFixed(), getSelectionRatio(), selectionBounds);
+        case NORTHWEST_EDGE:
+            return new ToNorthwestChangeStrategy(
+                    getSelection(), isSelectionRatioFixed(), getSelectionRatio(), selectionBounds);
+        default:
+            throw new IllegalArgumentException("The position " + selectionEvent.getPosition() //$NON-NLS-1$
+                    + " is not fully implemented."); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Checks whether the selection will be deactivated if the mouse is clicked at the {@link SelectionEvent}.
+     * 
+     * @param selectionEvent
+     *            the selection event which will be checked
+     * @return {@code true} if the selection event is such that the selection will be deactivated if the mouse is only
+     *         clicked
+     */
+    private static boolean willDeactivateSelectionIfClick(SelectionEvent selectionEvent) {
+        boolean rightClick = selectionEvent.getMouseEvent().getButton() == MouseButton.SECONDARY;
+        boolean outOfAreaClick = selectionEvent.getPosition() == CoordinatePosition.OUT_OF_RECTANGLE;
+
+        return rightClick || outOfAreaClick;
+    }
+
+    /* ************************************************************************
+     *                                                                         *
+     * Usability Access Functions to SnapshotView Properties                   *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * The control's width.
+     * 
+     * @return {@link SnapshotView#getWidth()}
+     */
+    private double getControlWidth() {
+        return getControl().getWidth();
+    }
+
+    /**
+     * The control's height.
+     * 
+     * @return {@link SnapshotView#getHeight()}
+     */
+    private double getControlHeight() {
+        return getControl().getHeight();
+    }
+
+    /**
+     * The currently displayed node.
+     * 
+     * @return {@link SnapshotView#getNode()}
+     */
+    private Node getNode() {
+        return getControl().getNode();
+    }
+
+    /**
+     * The current selection.
+     * 
+     * @return {@link SnapshotView#getSelection()}
+     */
+    private Rectangle2D getSelection() {
+        return getControl().getSelection();
+    }
+    /**
+     * Indicates whether the current selection has a fixed ratio.
+     * 
+     * @return {@link SnapshotView#isSelectionRatioFixed()}
+     */
+    private boolean isSelectionRatioFixed() {
+        return getControl().isSelectionRatioFixed();
+    }
+
+    /**
+     * The current selection's fixed ratio.
+     * 
+     * @return {@link SnapshotView#getFixedSelectionRatio()}
+     */
+    private double getSelectionRatio() {
+        return getControl().getFixedSelectionRatio();
+    }
+
+    /* ************************************************************************
+     *                                                                         *
+     * Inner Classes                                                           *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * A selection event encapsulates a {@link MouseEvent} and adds some additional information like the coordinates
+     * relative to the node's preferred size and its position relative to a selection.
+     */
+    private static class SelectionEvent {
+
+        /**
+         * The {@link MouseEvent} for which this selection event was created.
+         */
+        private final MouseEvent mouseEvent;
+
+        /**
+         * The coordinates of the mouse event as a {@link Point2D}.
+         */
+        private final Point2D point;
+
+        /**
+         * The {@link Rectangle2D} within which any new selection must be contained.
+         */
+        private final Rectangle2D selectionBounds;
+
+        /**
+         * The {@link #point}'s position relative to a possible selection.
+         */
+        private final CoordinatePosition position;
+
+        /**
+         * Creates a new selection event with the specified arguments.
+         * 
+         * @param mouseEvent
+         *            the {@link MouseEvent} for which this selection event is created
+         * @param point
+         *            the coordinates of the mouse event as a {@link Point2D}
+         * @param selectionBounds
+         *            the {@link Rectangle2D} within which any new selection must be contained
+         * @param position
+         *            the point's position relative to a possible selection
+         */
+        public SelectionEvent(
+                MouseEvent mouseEvent, Point2D point, Rectangle2D selectionBounds, CoordinatePosition position) {
+
+            this.mouseEvent = mouseEvent;
+            this.point = point;
+            this.selectionBounds = selectionBounds;
+            this.position = position;
+        }
+
+        /**
+         * @return the mouse event for which this selection event was created
+         */
+        public MouseEvent getMouseEvent() {
+            return mouseEvent;
+        }
+
+        /**
+         * @return the coordinates of the mouse event in the nodes' preferred coordinates
+         */
+        public Point2D getPoint() {
+            return point;
+        }
+
+        /**
+         * @return the {@link Rectangle2D} within which any new selection must be contained
+         */
+        public Rectangle2D getSelectionBounds() {
+            return selectionBounds;
+        }
+
+        /**
+         * @return {@code true} if the {@link #getSelectionBounds() selectionBounds} contains the {@link #getPoint()
+         *         point}; otherwise {@code false}
+         */
+        public boolean isPointInSelectionBounds() {
+            return selectionBounds.contains(point);
+        }
+
+        /**
+         * @return the {@link #getPoint() point}'s position relative to a possible selection.
+         */
+        public CoordinatePosition getPosition() {
+            return position;
+        }
+
+    }
+
+    /**
+     * Handles the actual change of a selection when the mouse is pressed, dragged and released.
+     */
+    private static interface SelectionChange {
+
+        /**
+         * Begins the selection change at the specified point.
+         * 
+         * @param point
+         *            the starting point of the selection change
+         */
+        public abstract void beginSelectionChange(Point2D point);
+
+        /**
+         * Continues the selection change to the specified point.
+         * 
+         * @param point
+         *            the next point of this selection change
+         */
+        public abstract void continueSelectionChange(Point2D point);
+
+        /**
+         * Ends the selection change at the specified point.
+         * 
+         * @param point
+         *            the final point of this selection change
+         */
+        public abstract void endSelectionChange(Point2D point);
+
+        /**
+         * The cursor for this selection change.
+         * 
+         * @return the cursor for this selection change
+         */
+        public abstract Cursor getCursor();
+
+    }
+
+    /**
+     * Implementation of {@link SelectionChange} which does not actually change anything.
+     */
+    private static class NoSelectionChange implements SelectionChange {
+
+        /**
+         * The singleton instance.
+         */
+        public static final NoSelectionChange INSTANCE = new NoSelectionChange();
+
+        /**
+         * Private constructor for singleton.
+         */
+        private NoSelectionChange() {
+            // nothing to do
+        }
+
+        @Override
+        public void beginSelectionChange(Point2D point) {
+            // nothing to do
+        }
+
+        @Override
+        public void continueSelectionChange(Point2D point) {
+            // nothing to do
+        }
+
+        @Override
+        public void endSelectionChange(Point2D point) {
+            // nothing to do
+        }
+
+        @Override
+        public Cursor getCursor() {
+            return Cursor.DEFAULT;
+        }
+
+    }
+
+    /**
+     * Executes the changes from a {@link Rectangle2DChangeStrategy} on a {@link SnapshotView}'s
+     * {@link SnapshotView#selectionProperty() selection} property. This includes to check whether the mouse moved from
+     * the change's start to end and to possibly deactivate the selection if not.
+     */
+    private static class SelectionChangeByStrategy implements SelectionChange {
+
+        // Attributes
+
+        /**
+         * The snapshot view whose selection will be changed.
+         */
+        private final SnapshotView snapshotView;
+
+        /**
+         * A function which sets the {@link SnapshotView#selectionChangingProperty() selectionChanging} property to the
+         * given value.
+         */
+        private final Consumer<Boolean> setSelectionChanging;
+
+        /**
+         * The executed change strategy.
+         */
+        private final Rectangle2DChangeStrategy selectionChangeStrategy;
+
+        /**
+         * The cursor during the selection change.
+         */
+        private final Cursor cursor;
+
+        /**
+         * Indicates if the selection will be deactivated if the mouse is only clicked (e.g. does not move between start
+         * and end).
+         */
+        private final boolean deactivateSelectionIfClick;
+
+        /**
+         * The change's starting point. Used to check whether the mouse moved.
+         */
+        private Point2D startingPoint;
+
+        /**
+         * Set to true as soon as the mouse moved away from the starting point.
+         */
+        private boolean mouseMoved;
+
+        // Constructor
+
+        /**
+         * Creates a new selection change for the specified {@link SnapshotView} using the specified
+         * {@link Rectangle2DChangeStrategy}.
+         * 
+         * @param snapshotView
+         *            the {@link SnapshotView} whose selection will be changed
+         * @param setSelectionChanging
+         *            a function which sets the {@link SnapshotView#selectionChangingProperty() selectionChanging}
+         *            property to the given value
+         * @param selectionChangeStrategy
+         *            the {@link Rectangle2DChangeStrategy} used to change the selection
+         * @param cursor
+         *            the {@link Cursor} used during the selection change
+         * @param deactivateSelectionIfClick
+         *            indicates whether the selection will be deactivated if the change is only a click
+         */
+        public SelectionChangeByStrategy(
+                SnapshotView snapshotView, Consumer<Boolean> setSelectionChanging,
+                Rectangle2DChangeStrategy selectionChangeStrategy, Cursor cursor, boolean deactivateSelectionIfClick) {
+
+            this.snapshotView = snapshotView;
+            this.setSelectionChanging = setSelectionChanging;
+            this.selectionChangeStrategy = selectionChangeStrategy;
+            this.cursor = cursor;
+            this.deactivateSelectionIfClick = deactivateSelectionIfClick;
+        }
+
+        // Selection Change
+
+        @Override
+        public void beginSelectionChange(Point2D point) {
+            startingPoint = point;
+            setSelectionChanging.accept(true);
+
+            Rectangle2D newSelection = selectionChangeStrategy.beginChange(point);
+            snapshotView.setSelection(newSelection);
+        }
+
+        @Override
+        public void continueSelectionChange(Point2D point) {
+            updateMouseMoved(point);
+
+            Rectangle2D newSelection = selectionChangeStrategy.continueChange(point);
+            snapshotView.setSelection(newSelection);
+        }
+
+        @Override
+        public void endSelectionChange(Point2D point) {
+            updateMouseMoved(point);
+
+            Rectangle2D newSelection = selectionChangeStrategy.endChange(point);
+            snapshotView.setSelection(newSelection);
+
+            boolean deactivateSelection = deactivateSelectionIfClick && !mouseMoved;
+            if (deactivateSelection) {
+                snapshotView.setSelection(null);
+            }
+            setSelectionChanging.accept(false);
+        }
+
+        /**
+         * Updates {@link #mouseMoved} by checking whether the specified point is different from the
+         * {@link #startingPoint}.
+         * 
+         * @param point
+         *            the point which will be compared to the {@link #startingPoint}
+         */
+        private void updateMouseMoved(Point2D point) {
+            // if the mouse already moved, do nothing
+            if (mouseMoved) {
+                return;
+            }
+
+            // if the mouse did not move yet, check whether it did now
+            boolean mouseMovedNow = !startingPoint.equals(point);
+            mouseMoved = mouseMovedNow;
+        }
+
+        // Attribute Access
+
+        @Override
+        public Cursor getCursor() {
+            return cursor;
+        }
+
+    }
+
+}
diff --git a/src/impl/org/controlsfx/control/validation/decoration-error.png b/src/impl/org/controlsfx/control/validation/decoration-error.png
new file mode 100644
index 0000000000000000000000000000000000000000..237b39fa3d06785b37423903644f3c13c7967cb4
Binary files /dev/null and b/src/impl/org/controlsfx/control/validation/decoration-error.png differ
diff --git a/src/impl/org/controlsfx/control/validation/decoration-warning.png b/src/impl/org/controlsfx/control/validation/decoration-warning.png
new file mode 100644
index 0000000000000000000000000000000000000000..0d351c5bff6d7085586d58807b006ca05e75af88
Binary files /dev/null and b/src/impl/org/controlsfx/control/validation/decoration-warning.png differ
diff --git a/src/impl/org/controlsfx/control/validation/required-indicator.png b/src/impl/org/controlsfx/control/validation/required-indicator.png
new file mode 100644
index 0000000000000000000000000000000000000000..4410d654cf218f43f5e65f2dbf29c1b03a846044
Binary files /dev/null and b/src/impl/org/controlsfx/control/validation/required-indicator.png differ
diff --git a/src/impl/org/controlsfx/i18n/Localization.java b/src/impl/org/controlsfx/i18n/Localization.java
new file mode 100644
index 0000000000000000000000000000000000000000..59c134cf2afdc148d2cdf63c0c756275a5f48f6f
--- /dev/null
+++ b/src/impl/org/controlsfx/i18n/Localization.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.i18n;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Localization {
+
+	private Localization() {
+	}
+
+	public static final String KEY_PREFIX = "@@"; //$NON-NLS-1$
+
+	private static final String LOCALE_BUNDLE_NAME = "controlsfx"; //$NON-NLS-1$
+	private static Locale locale = null;
+
+	/**
+	 * Returns the Locale object that is associated with ControlsFX.
+	 * 
+	 * @return the global ControlsFX locale
+	 */
+	public static final Locale getLocale() {
+		// following allows us to have a "dynamic" locale based on OS/JDK
+		return locale == null ? Locale.getDefault() : locale;
+	}
+
+	/**
+	 * Sets locale which will be used as ControlsFX locale
+	 * 
+	 * @param newLocale
+	 *            null is allowed and will be interpreted as default locale
+	 */
+	public static final void setLocale(final Locale newLocale) {
+		locale = newLocale;
+	}
+
+	private static Locale resourceBundleLocale = null; // has to be null initially
+	private static ResourceBundle resourceBundle = null;
+
+	private static synchronized final ResourceBundle getLocaleBundle() {
+
+		Locale currentLocale = getLocale();
+		if (!currentLocale.equals(resourceBundleLocale)) {
+			resourceBundleLocale = currentLocale;
+			resourceBundle = ResourceBundle.getBundle(LOCALE_BUNDLE_NAME,
+					resourceBundleLocale, Localization.class.getClassLoader());
+		}
+		return resourceBundle;
+
+	}
+
+	/**
+	 * Returns a string localized using currently set locale
+	 * 
+	 * @param key resource bundle key
+	 * @return localized text or formatted key if not found
+	 */
+	public static final String getString(final String key) {
+		try {
+			return getLocaleBundle().getString(key);
+		} catch (MissingResourceException ex) {
+			return String.format("<%s>", key); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Converts text to localization key,
+	 * currently by prepending it with the KEY_PREFIX
+	 * 
+	 * @param text
+	 * @return localization key
+	 */
+	public static final String asKey(String text) {
+		return KEY_PREFIX + text;
+	}
+
+	/**
+	 * Checks if the text is a localization key
+	 * 
+	 * @param text
+	 * @return true if text is a localization key
+	 */
+	public static final boolean isKey(String text) {
+		return text != null && text.startsWith(KEY_PREFIX);
+	}
+
+	/**
+	 * Tries to localize the text. If the text is a localization key - and attempt will be made to 
+	 * use it for localization, otherwise the text is returned as is
+	 * 
+	 * @param text
+	 * @return
+	 */
+	public static String localize(String text) {
+		return isKey(text) ? getString(text.substring(KEY_PREFIX.length())
+				.trim()) : text;
+	}
+
+}
diff --git a/src/impl/org/controlsfx/i18n/SimpleLocalizedStringProperty.java b/src/impl/org/controlsfx/i18n/SimpleLocalizedStringProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..44ce99643f391d20d1a7d4bc682faeb8c7159b87
--- /dev/null
+++ b/src/impl/org/controlsfx/i18n/SimpleLocalizedStringProperty.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.i18n;
+
+import javafx.beans.property.SimpleStringProperty;
+
+/**
+ * A special implementation of string property which assumes that its content may be a key and 
+ * attempts to get localized text resource base on it. 
+ * 
+ * It is intended for internal use only and will not work for bidirectional binding. 
+ */
+public class SimpleLocalizedStringProperty extends SimpleStringProperty {
+
+	public SimpleLocalizedStringProperty() {
+	}
+
+	public SimpleLocalizedStringProperty(String initialValue) {
+		super(initialValue);
+	}
+
+	public SimpleLocalizedStringProperty(Object bean, String name) {
+		super(bean, name);
+	}
+
+	public SimpleLocalizedStringProperty(Object bean, String name,
+			String initialValue) {
+		super(bean, name, initialValue);
+	}
+
+	@Override public String getValue() {
+		return Localization.localize(super.getValue());
+	}
+}
diff --git a/src/impl/org/controlsfx/i18n/Translation.java b/src/impl/org/controlsfx/i18n/Translation.java
new file mode 100644
index 0000000000000000000000000000000000000000..a972bb489287036b1d802edfe8c8b090cef21396
--- /dev/null
+++ b/src/impl/org/controlsfx/i18n/Translation.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.i18n;
+
+import java.nio.file.Path;
+import java.util.Locale;
+
+public class Translation implements Comparable<Translation> {
+
+    private final String localeString;
+    private final Locale locale;
+    private final Path path;
+    
+    public Translation(String locale, Path path) {
+        this.localeString = locale;
+        this.path = path;
+        
+        String[] split = localeString.split("_"); //$NON-NLS-1$
+        if (split.length == 1) {
+            this.locale = new Locale(localeString);
+        } else if (split.length == 2) {
+            this.locale = new Locale(split[0], split[1]);
+        } else if (split.length == 3) {
+            this.locale = new Locale(split[0], split[1], split[2]);
+        } else {
+            throw new IllegalArgumentException("Unknown locale string '" + locale + "'"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+    }
+    
+    public final String getLocaleString() {
+        return localeString;
+    }
+    
+    public final Locale getLocale() {
+        return locale;
+    }
+    
+    public final Path getPath() {
+        return path;
+    }
+    
+    @Override public String toString() {
+        return localeString;
+    }
+    
+    @Override public int compareTo(Translation o) {
+        if (o == null) return 1;
+        return localeString.compareTo(o.localeString);
+    }
+}
diff --git a/src/impl/org/controlsfx/i18n/Translations.java b/src/impl/org/controlsfx/i18n/Translations.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab9035598dfa945ca6820b8002ff2f7e0ac5ec99
--- /dev/null
+++ b/src/impl/org/controlsfx/i18n/Translations.java
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.i18n;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.DirectoryIteratorException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+public class Translations {
+
+    private static List<Translation> translations = new ArrayList<>();
+
+    static {
+        // firstly try to read from the controlsfx jar
+        File file = new File(Translations.class.getProtectionDomain().getCodeSource().getLocation().getPath());
+        if (file.getName().endsWith(".jar")) { //$NON-NLS-1$
+            Path jarFile = file.toPath();
+            try (FileSystem fs = FileSystems.newFileSystem(jarFile, null)) {
+                fs.getRootDirectories().forEach(path -> loadFrom(path));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        
+        // look in src directory
+        if (translations.isEmpty()) {
+            // try to read the files from the local filesystem (good for when ControlsFX
+            // is being run from within a developers IDE)
+            Path srcDir = new File("src/main/resources").toPath(); //$NON-NLS-1$
+            loadFrom(srcDir);
+        }
+        
+        // look in bin directory
+        if (translations.isEmpty()) {
+            Path binDir = new File("bin").toPath(); //$NON-NLS-1$
+            loadFrom(binDir);
+        }
+        
+        // look in bin directory an alternative way (good for when running 
+        // controlsfx-samples)
+        if (translations.isEmpty()) {
+            if (file.getAbsolutePath().endsWith("controlsfx" + File.separator + "bin")) { //$NON-NLS-1$ //$NON-NLS-2$
+                loadFrom(file.toPath());
+            }
+        }
+        
+        Collections.sort(translations);
+    }
+    
+    private static void loadFrom(Path rootPath) {
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(rootPath)) {
+            for (Path path : stream) {
+                String filename = path.getFileName().toString();
+
+                if (! filename.startsWith("controlsfx") && ! filename.endsWith(".properties")) { //$NON-NLS-1$ //$NON-NLS-2$
+                    continue;
+                }
+
+                if ("controlsfx.properties".equals(filename)) { //$NON-NLS-1$
+                    translations.add(new Translation("en", path)); //$NON-NLS-1$
+                } else if (filename.contains("_")) { //$NON-NLS-1$
+                    String locale = filename.substring(11, filename.indexOf(".properties")); //$NON-NLS-1$
+                    translations.add(new Translation(locale, path));
+                } else {
+                    throw new IllegalStateException("Unknown translation file '" + path + "'."); //$NON-NLS-1$ //$NON-NLS-2$
+                }
+
+            }
+        } catch (IOException | DirectoryIteratorException x) {
+            // no-op
+        }
+    }
+
+    private Translations() {
+        // no-op
+    }
+    
+    public static Optional<Translation> getTranslation(String localeString) {
+        for (Translation t : translations) {
+            if (localeString.equals(t.getLocaleString())) {
+                return Optional.of(t);
+            }
+        }
+        return Optional.empty();
+    }
+
+    public static List<Translation> getAllTranslations() {
+        return translations;
+    }
+
+    public static List<Locale> getAllTranslationLocales() {
+        return translations.stream().map((Translation t) -> t.getLocale()).collect(Collectors.toList());
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/AutoCompletePopup.java b/src/impl/org/controlsfx/skin/AutoCompletePopup.java
new file mode 100644
index 0000000000000000000000000000000000000000..e242d02b9bf18f7463c3d33158b48150526c841f
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/AutoCompletePopup.java
@@ -0,0 +1,233 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+
+import com.sun.javafx.event.EventHandlerManager;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ObjectPropertyBase;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.Event;
+import javafx.event.EventDispatchChain;
+import javafx.event.EventHandler;
+import javafx.event.EventType;
+import javafx.scene.Node;
+import javafx.scene.control.PopupControl;
+import javafx.scene.control.Skin;
+import javafx.stage.Window;
+import javafx.util.StringConverter;
+
+/**
+ * The auto-complete-popup provides an list of available suggestions in order
+ * to complete current user input.
+ */
+public class AutoCompletePopup<T> extends PopupControl{
+
+    /***************************************************************************
+     *                                                                         *
+     * Private fields                                                          *
+     *                                                                         *
+     **************************************************************************/
+
+    private final static int TITLE_HEIGHT = 28; // HACK: Hard-coded title-bar height
+    private final ObservableList<T> suggestions = FXCollections.observableArrayList();
+    private StringConverter<T> converter;
+    /**
+     * The maximum number of rows to be visible in the popup when it is
+     * showing. By default this value is 10, but this can be changed to increase
+     * or decrease the height of the popup.
+     */
+    private IntegerProperty visibleRowCount = new SimpleIntegerProperty(this, "visibleRowCount", 10);
+
+    /***************************************************************************
+     *                                                                         *
+     * Inner classes                                                           *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Represents an Event which is fired when the user has selected a suggestion
+     * for auto-complete
+     *
+     * @param <TE>
+     */
+    @SuppressWarnings("serial")
+    public static class SuggestionEvent<TE> extends Event {
+        @SuppressWarnings("rawtypes")
+        public static final EventType<SuggestionEvent> SUGGESTION = new EventType<>("SUGGESTION"); //$NON-NLS-1$
+
+        private final TE suggestion;
+
+        public SuggestionEvent(TE suggestion) {
+            super(SUGGESTION);
+            this.suggestion = suggestion;
+        }
+
+        /**
+         * Returns the suggestion which was chosen by the user
+         * @return
+         */
+        public TE getSuggestion() {
+            return suggestion;
+        }
+    }
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Creates a new AutoCompletePopup
+     */
+    public AutoCompletePopup(){
+        this.setAutoFix(true);
+        this.setAutoHide(true);
+        this.setHideOnEscape(true);
+
+        getStyleClass().add(DEFAULT_STYLE_CLASS);
+    }
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+
+    /**
+     * Get the suggestions presented by this AutoCompletePopup
+     * @return
+     */
+    public ObservableList<T> getSuggestions() {
+        return suggestions;
+    }
+
+    /**
+     * Show this popup right below the given Node
+     * @param node
+     */
+    public void show(Node node){
+
+        if(node.getScene() == null || node.getScene().getWindow() == null)
+            throw new IllegalStateException("Can not show popup. The node must be attached to a scene/window."); //$NON-NLS-1$
+
+        if(isShowing()){
+            return;
+        }
+        
+        Window parent = node.getScene().getWindow();
+        this.show(
+                parent,
+                parent.getX() + node.localToScene(0, 0).getX() +
+                node.getScene().getX(),
+                parent.getY() + node.localToScene(0, 0).getY() +
+                node.getScene().getY() + TITLE_HEIGHT);
+
+    }
+
+    /**
+     * Set the string converter used to turn a generic suggestion into a string
+     */
+    public void setConverter(StringConverter<T> converter) {
+		this.converter = converter;
+	}
+    
+    /**
+     * Get the string converter used to turn a generic suggestion into a string
+     */
+	public StringConverter<T> getConverter() {
+		return converter;
+	}
+
+    public final void setVisibleRowCount(int value) {
+        visibleRowCount.set(value);
+    }
+
+    public final int getVisibleRowCount() {
+        return visibleRowCount.get();
+    }
+
+    public final IntegerProperty visibleRowCountProperty() {
+        return visibleRowCount;
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Properties                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+
+    private final EventHandlerManager eventHandlerManager = new EventHandlerManager(this);
+
+    public final ObjectProperty<EventHandler<SuggestionEvent<T>>> onSuggestionProperty() { return onSuggestion; }
+    public final void setOnSuggestion(EventHandler<SuggestionEvent<T>> value) { onSuggestionProperty().set(value); }
+    public final EventHandler<SuggestionEvent<T>> getOnSuggestion() { return onSuggestionProperty().get(); }
+    private ObjectProperty<EventHandler<SuggestionEvent<T>>> onSuggestion = new ObjectPropertyBase<EventHandler<SuggestionEvent<T>>>() {
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        @Override protected void invalidated() {
+            eventHandlerManager.setEventHandler(SuggestionEvent.SUGGESTION, (EventHandler<SuggestionEvent>)(Object)get());
+        }
+
+        @Override
+        public Object getBean() {
+            return AutoCompletePopup.this;
+        }
+
+        @Override
+        public String getName() {
+            return "onSuggestion"; //$NON-NLS-1$
+        }
+    };
+
+    /**{@inheritDoc}*/
+    @Override public EventDispatchChain buildEventDispatchChain(EventDispatchChain tail) {
+        return super.buildEventDispatchChain(tail).append(eventHandlerManager);
+    } 
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Stylesheet Handling                                                     *
+     *                                                                         *
+     **************************************************************************/
+
+    public static final String DEFAULT_STYLE_CLASS = "auto-complete-popup"; //$NON-NLS-1$
+
+    @Override
+    protected Skin<?> createDefaultSkin() {
+        return new AutoCompletePopupSkin<>(this);
+    }
+
+}
diff --git a/src/impl/org/controlsfx/skin/AutoCompletePopupSkin.java b/src/impl/org/controlsfx/skin/AutoCompletePopupSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..0edfac6d90dcaac8c3952d1bc54c89bf2e24fe19
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/AutoCompletePopupSkin.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2014, 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import javafx.beans.binding.Bindings;
+import javafx.event.Event;
+import javafx.scene.Node;
+import javafx.scene.control.ListView;
+import javafx.scene.control.Skin;
+import javafx.scene.control.cell.TextFieldListCell;
+import javafx.scene.input.MouseButton;
+import org.controlsfx.control.textfield.AutoCompletionBinding;
+
+
+public class AutoCompletePopupSkin<T> implements Skin<AutoCompletePopup<T>> {
+
+    private final AutoCompletePopup<T> control;
+    private final ListView<T> suggestionList;
+    final int LIST_CELL_HEIGHT = 24;
+
+    public AutoCompletePopupSkin(AutoCompletePopup<T> control){
+        this.control = control;
+        suggestionList = new ListView<>(control.getSuggestions());
+
+        suggestionList.getStyleClass().add(AutoCompletePopup.DEFAULT_STYLE_CLASS);
+
+        suggestionList.getStylesheets().add(AutoCompletionBinding.class
+        		.getResource("autocompletion.css").toExternalForm()); //$NON-NLS-1$
+        /**
+         * Here we bind the prefHeightProperty to the minimum height between the
+         * max visible rows and the current items list. We also add an arbitrary
+         * 5 number because when we have only one item we have the vertical
+         * scrollBar showing for no reason.
+         */
+        suggestionList.prefHeightProperty().bind(
+                Bindings.min(control.visibleRowCountProperty(), Bindings.size(suggestionList.getItems()))
+                .multiply(LIST_CELL_HEIGHT).add(18));
+        suggestionList.setCellFactory(TextFieldListCell.forListView(control.getConverter()));
+        
+        //Allowing the user to control ListView width.
+        suggestionList.prefWidthProperty().bind(control.prefWidthProperty());
+        suggestionList.maxWidthProperty().bind(control.maxWidthProperty());
+        suggestionList.minWidthProperty().bind(control.minWidthProperty());
+        registerEventListener();
+    }
+
+    private void registerEventListener(){
+        suggestionList.setOnMouseClicked(me -> {
+            if (me.getButton() == MouseButton.PRIMARY){
+                onSuggestionChoosen(suggestionList.getSelectionModel().getSelectedItem());
+            }
+        });
+
+
+        suggestionList.setOnKeyPressed(ke -> {
+            switch (ke.getCode()) {
+                case ENTER:
+                    onSuggestionChoosen(suggestionList.getSelectionModel().getSelectedItem());
+                    break;
+                case ESCAPE:
+                    if (control.isHideOnEscape()) {
+                        control.hide();
+                    }
+                    break;
+                default:
+                    break;
+            }
+        });
+    }
+
+    private void onSuggestionChoosen(T suggestion){
+        if(suggestion != null) {
+            Event.fireEvent(control, new AutoCompletePopup.SuggestionEvent<>(suggestion));
+        }
+    }
+
+
+    @Override
+    public Node getNode() {
+        return suggestionList;
+    }
+
+    @Override
+    public AutoCompletePopup<T> getSkinnable() {
+        return control;
+    }
+
+    @Override
+    public void dispose() {
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/BreadCrumbBarSkin.java b/src/impl/org/controlsfx/skin/BreadCrumbBarSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..1bd8f98e4b82e936df1809a01373d8690dd5e861
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/BreadCrumbBarSkin.java
@@ -0,0 +1,381 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeItem.TreeModificationEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.ArcTo;
+import javafx.scene.shape.ClosePath;
+import javafx.scene.shape.HLineTo;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+import javafx.util.Callback;
+
+import org.controlsfx.control.BreadCrumbBar;
+import org.controlsfx.control.BreadCrumbBar.BreadCrumbActionEvent;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+import com.sun.javafx.scene.traversal.Algorithm;
+import com.sun.javafx.scene.traversal.Direction;
+import com.sun.javafx.scene.traversal.ParentTraversalEngine;
+import com.sun.javafx.scene.traversal.TraversalContext;
+
+/**
+ * Basic Skin implementation for the {@link BreadCrumbBar}
+ *
+ * @param <T>
+ */
+public class BreadCrumbBarSkin<T> extends BehaviorSkinBase<BreadCrumbBar<T>, BehaviorBase<BreadCrumbBar<T>>> {
+        
+    private static final String STYLE_CLASS_FIRST = "first"; //$NON-NLS-1$
+
+    public BreadCrumbBarSkin(final BreadCrumbBar<T> control) {
+        super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
+        control.selectedCrumbProperty().addListener(selectedPathChangeListener);
+        updateSelectedPath(getSkinnable().selectedCrumbProperty().get(), null);
+        fixFocusTraversal();
+    }
+
+    // https://bitbucket.org/controlsfx/controlsfx/issue/453/breadcrumbbar-keyboard-focus-traversal-is
+    // ContainerTabOrder will fail with LEFT/RIGHT navigation, since the buttons in bread crumb overlap
+    private void fixFocusTraversal() {
+
+        ParentTraversalEngine engine = new ParentTraversalEngine(getSkinnable(), new Algorithm() {
+
+            @Override
+            public Node select(Node owner, Direction dir, TraversalContext context) {
+                Node node = null;
+                int idx = getChildren().indexOf(owner);
+                switch(dir) {
+                    case NEXT:
+                    case NEXT_IN_LINE:
+                    case RIGHT:
+                        if (idx < getChildren().size() - 1) {
+                            node = getChildren().get(idx+1);
+                        }
+                    break;
+                    case PREVIOUS:
+                    case LEFT:
+                        if (idx > 0) {
+                            node = getChildren().get(idx-1);
+                        }
+                        break;
+                }
+                return node;
+            }
+
+            @Override
+            public Node selectFirst(TraversalContext context) {
+                Node first = null;
+                if (!getChildren().isEmpty()) {
+                    first = getChildren().get(0);
+                }
+                return first;
+            }
+
+            @Override
+            public Node selectLast(TraversalContext context) {
+                Node last = null;
+                if (!getChildren().isEmpty()) {
+                    last = getChildren().get(getChildren().size()-1);
+                }
+                return last;
+            }
+        });
+        engine.setOverriddenFocusTraversability(false);
+        getSkinnable().setImpl_traversalEngine(engine);
+
+    }
+
+    private final ChangeListener<TreeItem<T>> selectedPathChangeListener =
+            (obs, oldItem, newItem) -> updateSelectedPath(newItem, oldItem);
+
+    private void updateSelectedPath(TreeItem<T> newTarget, TreeItem<T> oldTarget) {
+        if(oldTarget != null){
+            // remove old listener
+            oldTarget.removeEventHandler(
+                    TreeItem.childrenModificationEvent(), treeChildrenModifiedHandler);
+        }
+        if(newTarget != null){
+            // add new listener
+            newTarget.addEventHandler(TreeItem.childrenModificationEvent(), treeChildrenModifiedHandler);
+        }
+        updateBreadCrumbs();
+    }
+
+
+    private final EventHandler<TreeModificationEvent<Object>> treeChildrenModifiedHandler = 
+            args -> updateBreadCrumbs();
+
+
+    private void updateBreadCrumbs() {
+        final BreadCrumbBar<T> buttonBar = getSkinnable();
+        final TreeItem<T> pathTarget = buttonBar.getSelectedCrumb();
+        final Callback<TreeItem<T>, Button> factory = buttonBar.getCrumbFactory();
+
+        getChildren().clear();
+
+        if(pathTarget != null){
+            List<TreeItem<T>> crumbs = constructFlatPath(pathTarget);
+
+            for (int i=0; i < crumbs.size(); i++) {
+                Button crumb = createCrumb(factory, crumbs.get(i));
+                crumb.setMnemonicParsing(false);
+                if (i == 0) {
+                    if (! crumb.getStyleClass().contains(STYLE_CLASS_FIRST)) {
+                        crumb.getStyleClass().add(STYLE_CLASS_FIRST);
+                    }
+                } else {
+                    crumb.getStyleClass().remove(STYLE_CLASS_FIRST);
+                }
+
+                getChildren().add(crumb);
+            }
+        }
+    }
+    
+    @Override protected void layoutChildren(double x, double y, double w, double h) {
+        for (int i = 0; i < getChildren().size(); i++) {
+            Node n = getChildren().get(i);
+            
+            double nw = snapSize(n.prefWidth(h));
+            double nh = snapSize(n.prefHeight(-1));
+            
+            if (i > 0) {
+                // We have to position the bread crumbs slightly overlapping
+                double ins = n instanceof BreadCrumbButton ?  ((BreadCrumbButton)n).getArrowWidth() : 0;
+                x = snapPosition(x - ins);
+            }
+
+            n.resize(nw, nh);
+            n.relocate(x, y);
+            x += nw;
+        }
+    }
+
+    /**
+     * Construct a flat list for the crumbs
+     * @param bottomMost The crumb node at the end of the path
+     * @return
+     */
+    private List<TreeItem<T>> constructFlatPath(TreeItem<T> bottomMost){
+        List<TreeItem<T>> path = new ArrayList<>();
+
+        TreeItem<T> current = bottomMost;
+        do {
+            path.add(current);
+            current = current.getParent();
+        } while (current != null);
+
+        Collections.reverse(path);
+        return path;
+    }
+
+    private Button createCrumb(
+            final Callback<TreeItem<T>, Button> factory,
+            final TreeItem<T> selectedCrumb) {
+
+        Button crumb = factory.call(selectedCrumb);
+        
+        crumb.getStyleClass().add("crumb"); //$NON-NLS-1$
+
+        // We want all buttons to have the same height
+        // so we bind their preferred height to the enclosing container
+//        crumb.prefHeightProperty().bind(getSkinnable().heightProperty());
+
+        // listen to the action event of each bread crumb
+        crumb.setOnAction(ae -> onBreadCrumbAction(selectedCrumb));
+
+        return crumb;
+    }
+
+    /**
+     * Occurs when a bread crumb gets the action event
+     * 
+     * @param crumbModel The crumb which received the action event
+     */
+    protected void onBreadCrumbAction(final TreeItem<T> crumbModel){
+        final BreadCrumbBar<T> breadCrumbBar = getSkinnable();
+
+        // fire the composite event in the breadCrumbBar
+        Event.fireEvent(breadCrumbBar, new BreadCrumbActionEvent<>(crumbModel));
+
+        // navigate to the clicked crumb
+        if(breadCrumbBar.isAutoNavigationEnabled()){
+            breadCrumbBar.setSelectedCrumb(crumbModel);
+        }
+    }
+
+    
+    
+    
+    /**
+     * Represents a BreadCrumb Button
+     * 
+     * <pre>
+     * ----------
+     *  \         \
+     *  /         /
+     * ----------
+     * </pre>
+     * 
+     * 
+     */
+    public static class BreadCrumbButton extends Button {
+
+        private final ObjectProperty<Boolean> first = new SimpleObjectProperty<>(this, "first"); //$NON-NLS-1$
+
+        private final double arrowWidth = 5;
+        private final double arrowHeight = 20;
+
+        /**
+         * Create a BreadCrumbButton
+         * 
+         * @param text Buttons text
+         */
+        public BreadCrumbButton(String text){
+            this(text, null);
+        }
+
+        /**
+         * Create a BreadCrumbButton
+         * @param text Buttons text
+         * @param gfx Gfx of the Button
+         */
+        public BreadCrumbButton(String text, Node gfx){
+            super(text, gfx);
+            first.set(false);
+
+            getStyleClass().addListener(new InvalidationListener() {
+                @Override public void invalidated(Observable arg0) {
+                    updateShape();
+                }
+            });
+
+            updateShape();
+        }
+
+        private void updateShape(){
+            this.setShape(createButtonShape());
+        }
+
+
+        /**
+         * Gets the crumb arrow with
+         * @return
+         */
+        public double getArrowWidth(){
+            return arrowWidth;
+        }
+
+        /**
+         * Create an arrow path
+         * 
+         * Based upon Uwe / Andy Till code snippet found here:
+         * @see http://ustesis.wordpress.com/2013/11/04/implementing-breadcrumbs-in-javafx/
+         * @return
+         */
+        private Path createButtonShape(){
+            // build the following shape (or home without left arrow)
+
+            //   --------
+            //  \         \
+            //  /         /
+            //   --------
+            Path path = new Path();
+
+            // begin in the upper left corner
+            MoveTo e1 = new MoveTo(0, 0);
+            path.getElements().add(e1);
+
+            // draw a horizontal line that defines the width of the shape
+            HLineTo e2 = new HLineTo();
+            // bind the width of the shape to the width of the button
+            e2.xProperty().bind(this.widthProperty().subtract(arrowWidth));
+            path.getElements().add(e2);
+
+            // draw upper part of right arrow
+            LineTo e3 = new LineTo();
+            // the x endpoint of this line depends on the x property of line e2
+            e3.xProperty().bind(e2.xProperty().add(arrowWidth));
+            e3.setY(arrowHeight / 2.0);
+            path.getElements().add(e3);
+
+            // draw lower part of right arrow
+            LineTo e4 = new LineTo();
+            // the x endpoint of this line depends on the x property of line e2
+            e4.xProperty().bind(e2.xProperty());
+            e4.setY(arrowHeight);
+            path.getElements().add(e4);
+
+            // draw lower horizontal line
+            HLineTo e5 = new HLineTo(0);
+            path.getElements().add(e5);
+
+            if(! getStyleClass().contains(STYLE_CLASS_FIRST)){
+                // draw lower part of left arrow
+                // we simply can omit it for the first Button
+                LineTo e6 = new LineTo(arrowWidth, arrowHeight / 2.0);
+                path.getElements().add(e6);
+            }else{
+                // draw an arc for the first bread crumb
+                ArcTo arcTo = new ArcTo();
+                arcTo.setSweepFlag(true);
+                arcTo.setX(0);
+                arcTo.setY(0);
+                arcTo.setRadiusX(15.0f);
+                arcTo.setRadiusY(15.0f);
+                path.getElements().add(arcTo);
+            }
+
+            // close path
+            ClosePath e7 = new ClosePath();
+            path.getElements().add(e7);
+            // this is a dummy color to fill the shape, it won't be visible
+            path.setFill(Color.BLACK);
+            
+            return path;
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/CheckComboBoxSkin.java b/src/impl/org/controlsfx/skin/CheckComboBoxSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e7d1f7c720f7332c7144a0d3d2333035949440a
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/CheckComboBoxSkin.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import java.util.Collections;
+
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.control.cell.CheckBoxListCell;
+import javafx.util.Callback;
+
+import org.controlsfx.control.CheckComboBox;
+
+import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList;
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+import com.sun.javafx.scene.control.skin.ComboBoxListViewSkin;
+
+public class CheckComboBoxSkin<T> extends BehaviorSkinBase<CheckComboBox<T>, BehaviorBase<CheckComboBox<T>>> {
+    
+    /**************************************************************************
+     * 
+     * Static fields
+     * 
+     **************************************************************************/
+
+    
+    
+    /**************************************************************************
+     * 
+     * fields
+     * 
+     **************************************************************************/
+    
+    // visuals
+    private final ComboBox<T> comboBox;
+    private final ListCell<T> buttonCell;
+    
+    // data
+    private final CheckComboBox<T> control;
+    private final ObservableList<T> items;
+    private final ReadOnlyUnbackedObservableList<Integer> selectedIndices;
+    private final ReadOnlyUnbackedObservableList<T> selectedItems;
+    
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+
+    @SuppressWarnings("unchecked")
+    public CheckComboBoxSkin(final CheckComboBox<T> control) {
+        super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
+        
+        this.control = control;
+        this.items = control.getItems();
+        
+        selectedIndices = (ReadOnlyUnbackedObservableList<Integer>) control.getCheckModel().getCheckedIndices();
+        selectedItems = (ReadOnlyUnbackedObservableList<T>) control.getCheckModel().getCheckedItems();
+        
+        comboBox = new ComboBox<T>(items) {
+            @Override protected javafx.scene.control.Skin<?> createDefaultSkin() {
+                return new ComboBoxListViewSkin<T>(this) {
+                    // overridden to prevent the popup from disappearing
+                    @Override protected boolean isHideOnClickEnabled() {
+                        return false;
+                    }
+                };
+            }
+        };
+        comboBox.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
+        
+        // installs a custom CheckBoxListCell cell factory
+        comboBox.setCellFactory(new Callback<ListView<T>, ListCell<T>>() {
+            @Override public ListCell<T> call(ListView<T> listView) {
+                CheckBoxListCell<T> result = new CheckBoxListCell<>(item -> control.getItemBooleanProperty(item));
+                result.converterProperty().bind(control.converterProperty());
+                return result;
+            };
+        });
+        
+        // we render the selection into a custom button cell, so that it can 
+        // be pretty printed (e.g. 'Item 1, Item 2, Item 10').
+        buttonCell = new ListCell<T>() {
+            @Override protected void updateItem(T item, boolean empty) {
+                // we ignore whatever item is selected, instead choosing
+                // to display the selected item text using commas to separate
+                // each item
+                setText(buildString());
+            }
+        };
+        comboBox.setButtonCell(buttonCell);
+        comboBox.setValue((T)buildString());
+        
+        // The zero is a dummy value - it just has to be legally within the bounds of the
+        // item count for the CheckComboBox items list.
+        selectedIndices.addListener((ListChangeListener<Integer>) c -> buttonCell.updateIndex(0));
+        
+        getChildren().add(comboBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Overriding public API
+     * 
+     **************************************************************************/
+    
+    @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return comboBox.minWidth(height);
+    }
+
+    @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return comboBox.minHeight(width);
+    }
+    
+    @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return comboBox.prefWidth(height);
+    }
+
+    @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return comboBox.prefHeight(width);
+    }
+    
+    @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return getSkinnable().prefWidth(height);
+    }
+
+    @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return getSkinnable().prefHeight(width);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Implementation
+     * 
+     **************************************************************************/
+    
+    private String buildString() {
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0, max = selectedItems.size(); i < max; i++) {
+            T item = selectedItems.get(i);
+            if (control.getConverter() == null) {
+                sb.append(item);
+            } else {
+                sb.append(control.getConverter().toString(item));
+            }
+            if (i < max - 1) {
+                sb.append(", "); //$NON-NLS-1$
+            }
+        }
+        return sb.toString();
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Support classes / enums
+     * 
+     **************************************************************************/
+    
+}
diff --git a/src/impl/org/controlsfx/skin/CustomTextFieldSkin.java b/src/impl/org/controlsfx/skin/CustomTextFieldSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..00aa8f699a890e452537aaeec7f5b76ff59b5f6e
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/CustomTextFieldSkin.java
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2013, 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import javafx.beans.property.ObjectProperty;
+import javafx.css.PseudoClass;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.StackPane;
+
+import com.sun.javafx.scene.control.behavior.TextFieldBehavior;
+import com.sun.javafx.scene.control.skin.TextFieldSkin;
+import com.sun.javafx.scene.text.HitInfo;
+
+public abstract class CustomTextFieldSkin extends TextFieldSkin {
+        
+    private static final PseudoClass HAS_NO_SIDE_NODE = PseudoClass.getPseudoClass("no-side-nodes"); //$NON-NLS-1$
+    private static final PseudoClass HAS_LEFT_NODE = PseudoClass.getPseudoClass("left-node-visible"); //$NON-NLS-1$
+    private static final PseudoClass HAS_RIGHT_NODE = PseudoClass.getPseudoClass("right-node-visible"); //$NON-NLS-1$
+    
+    private Node left;
+    private StackPane leftPane;
+    private Node right;
+    private StackPane rightPane;
+    
+    private final TextField control;
+    
+    public CustomTextFieldSkin(final TextField control) {
+        super(control, new TextFieldBehavior(control));
+        
+        this.control = control;
+        updateChildren();
+        
+        registerChangeListener(leftProperty(), "LEFT_NODE"); //$NON-NLS-1$
+        registerChangeListener(rightProperty(), "RIGHT_NODE"); //$NON-NLS-1$
+        registerChangeListener(control.focusedProperty(), "FOCUSED"); //$NON-NLS-1$
+    }
+    
+    public abstract ObjectProperty<Node> leftProperty();
+    public abstract ObjectProperty<Node> rightProperty();
+    
+    @Override protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+        
+        if (p == "LEFT_NODE" || p == "RIGHT_NODE") { //$NON-NLS-1$ //$NON-NLS-2$
+            updateChildren();
+        }
+    }
+    
+    private void updateChildren() {
+        Node newLeft = leftProperty().get();
+        if (newLeft != null) {
+            getChildren().remove(leftPane);
+            leftPane = new StackPane(newLeft);
+            leftPane.setAlignment(Pos.CENTER_LEFT);
+            leftPane.getStyleClass().add("left-pane"); //$NON-NLS-1$
+            getChildren().add(leftPane);
+            left = newLeft;
+        }
+        
+        Node newRight = rightProperty().get();
+        if (newRight != null) {
+            getChildren().remove(rightPane);
+            rightPane = new StackPane(newRight);
+            rightPane.setAlignment(Pos.CENTER_RIGHT);
+            rightPane.getStyleClass().add("right-pane"); //$NON-NLS-1$
+            getChildren().add(rightPane);
+            right = newRight;
+        }
+        
+        control.pseudoClassStateChanged(HAS_LEFT_NODE, left != null);
+        control.pseudoClassStateChanged(HAS_RIGHT_NODE, right != null);
+        control.pseudoClassStateChanged(HAS_NO_SIDE_NODE, left == null && right == null);
+    }
+    
+    @Override protected void layoutChildren(double x, double y, double w, double h) {
+        final double fullHeight = h + snappedTopInset() + snappedBottomInset();
+        
+        final double leftWidth = leftPane == null ? 0.0 : snapSize(leftPane.prefWidth(fullHeight));
+        final double rightWidth = rightPane == null ? 0.0 : snapSize(rightPane.prefWidth(fullHeight));
+        
+        final double textFieldStartX = snapPosition(x) + snapSize(leftWidth);
+        final double textFieldWidth = w - snapSize(leftWidth) - snapSize(rightWidth);
+        
+        super.layoutChildren(textFieldStartX, 0, textFieldWidth, fullHeight);
+
+        if (leftPane != null) {
+            final double leftStartX = 0;
+            leftPane.resizeRelocate(leftStartX, 0, leftWidth, fullHeight);
+        }
+        
+        if (rightPane != null) {
+            final double rightStartX = rightPane == null ? 0.0 : w - rightWidth + snappedLeftInset();
+            rightPane.resizeRelocate(rightStartX, 0, rightWidth, fullHeight);
+        }
+    }
+    
+    @Override
+    public HitInfo getIndex(double x, double y) {
+        /**
+         * This resolves https://bitbucket.org/controlsfx/controlsfx/issue/476
+         * when we have a left Node and the click point is badly returned
+         * because we weren't considering the shift induced by the leftPane.
+         */
+        final double leftWidth = leftPane == null ? 0.0 : snapSize(leftPane.prefWidth(getSkinnable().getHeight()));
+        return super.getIndex(x - leftWidth, y);
+    }
+    
+    @Override
+    protected double computePrefWidth(double h, double topInset, double rightInset, double bottomInset, double leftInset) {
+        final double pw = super.computePrefWidth(h, topInset, rightInset, bottomInset, leftInset);
+        final double leftWidth = leftPane == null ? 0.0 : snapSize(leftPane.prefWidth(h));
+        final double rightWidth = rightPane == null ? 0.0 : snapSize(rightPane.prefWidth(h));
+    
+        return pw + leftWidth + rightWidth;
+    }
+    
+    @Override
+    protected double computePrefHeight(double w, double topInset, double rightInset, double bottomInset, double leftInset) {
+        final double ph = super.computePrefHeight(w, topInset, rightInset, bottomInset, leftInset);
+        final double leftHeight = leftPane == null ? 0.0 : snapSize(leftPane.prefHeight(-1));
+        final double rightHeight = rightPane == null ? 0.0 : snapSize(rightPane.prefHeight(-1));
+        
+        return Math.max(ph, Math.max(leftHeight, rightHeight));
+    }
+//    
+//    @Override
+//    protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+//        return computePrefWidth(height, topInset, rightInset, bottomInset, leftInset);
+//}
+}
diff --git a/src/impl/org/controlsfx/skin/DecorationPane.java b/src/impl/org/controlsfx/skin/DecorationPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb8cf8768c95ff703b2d38fe28bf8be48913bbfb
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/DecorationPane.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.layout.StackPane;
+
+import org.controlsfx.control.decoration.Decoration;
+import org.controlsfx.control.decoration.Decorator;
+
+public class DecorationPane extends StackPane {
+    
+    // maps from a node to a list of its decoration nodes
+    private final Map<Node, List<Node>> nodeDecorationMap = new WeakHashMap<>();
+    
+    ChangeListener<Boolean> visibilityListener = new ChangeListener<Boolean>() {
+        @Override public void changed(ObservableValue<? extends Boolean> o, Boolean wasVisible, Boolean isVisible) {
+            BooleanProperty p = (BooleanProperty)o;
+            Node n = (Node) p.getBean();
+            
+            removeAllDecorationsOnNode(n, Decorator.getDecorations(n));
+            Decorator.removeAllDecorations(n);
+        }
+    };
+
+    public DecorationPane() {
+        // Make DecorationPane transparent
+        setBackground(null);
+    }
+        
+    public void setRoot(Node root) {
+        getChildren().setAll(root);
+    }
+    
+    public void updateDecorationsOnNode(Node targetNode, List<Decoration> added, List<Decoration> removed) {
+        removeAllDecorationsOnNode(targetNode, removed);
+        addAllDecorationsOnNode(targetNode, added);
+    }
+
+    private void showDecoration(Node targetNode, Decoration decoration) {
+        Node decorationNode = decoration.applyDecoration(targetNode);
+        if (decorationNode != null) {
+            List<Node> decorationNodes = nodeDecorationMap.get(targetNode);
+            if (decorationNodes == null) {
+                decorationNodes = new ArrayList<>();
+                nodeDecorationMap.put(targetNode, decorationNodes);
+            }
+            decorationNodes.add(decorationNode);
+            
+            if (!getChildren().contains(decorationNode)) {
+                getChildren().add(decorationNode);
+                StackPane.setAlignment(decorationNode, Pos.TOP_LEFT); // TODO support for all positions.
+            }
+        }
+        
+        targetNode.visibleProperty().addListener(visibilityListener);
+    }
+
+    private void removeAllDecorationsOnNode(Node targetNode, List<Decoration> decorations) {
+        if (decorations == null || targetNode == null) return;
+        
+        // We need to do two things: 
+        // 1) Remove the decoration node (if it exists) from the nodeDecorationMap
+        //    for the targetNode, if it exists.
+        List<Node> decorationNodes = nodeDecorationMap.remove(targetNode);
+        if (decorationNodes != null) {
+            for (Node decorationNode : decorationNodes) {
+                boolean success = getChildren().remove(decorationNode);
+                if (! success) {
+                    throw new IllegalStateException("Could not remove decoration " +  //$NON-NLS-1$
+                            decorationNode + " from decoration pane children list: " +  //$NON-NLS-1$
+                            getChildren());
+                }
+            }
+        }
+        
+        // 2) Tell the decoration to remove itself from the target node (if necessary)
+        for (Decoration decoration : decorations) {
+            decoration.removeDecoration(targetNode);
+        }
+    }
+    
+    private void addAllDecorationsOnNode(Node targetNode, List<Decoration> decorations) {
+        if (decorations == null) return;
+        for (Decoration decoration : decorations) {
+            showDecoration(targetNode, decoration);
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/ExpandableTableRowSkin.java b/src/impl/org/controlsfx/skin/ExpandableTableRowSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8b5f8328103c6d6df4bf721f67931f013c17585
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/ExpandableTableRowSkin.java
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import com.sun.javafx.scene.control.skin.TableRowSkin;
+import javafx.scene.Node;
+import javafx.scene.control.TableRow;
+import org.controlsfx.control.table.TableRowExpanderColumn;
+
+/**
+ * This skin is installed when you assign a {@link org.controlsfx.control.table.TableRowExpanderColumn} to a TableView.
+ * The skin will render the expanded node produced by the
+ * {@link org.controlsfx.control.table.TableRowExpanderColumn#expandedNodeCallback} whenever the expanded state is
+ * changed to true for a certain row.
+ *
+ * @param <S> The type of items in the TableRow
+ */
+public class ExpandableTableRowSkin<S> extends TableRowSkin<S> {
+    private final TableRow<S> tableRow;
+    private TableRowExpanderColumn<S> expander;
+    private Double tableRowPrefHeight = -1D;
+
+    /**
+     * Create the ExpandableTableRowSkin and listen to changes for the item this table row represents. When the
+     * item is changed, the old expanded node, if any, is removed from the children list of the TableRow.
+     *
+     * @param tableRow The table row to apply this skin for
+     * @param expander The expander column, used to retrieve the expanded node when this row is expanded
+     */
+    public ExpandableTableRowSkin(TableRow<S> tableRow, TableRowExpanderColumn<S> expander) {
+        super(tableRow);
+        this.tableRow = tableRow;
+        this.expander = expander;
+        tableRow.itemProperty().addListener((observable, oldValue, newValue) -> {
+            if (oldValue != null) {
+                Node expandedNode = this.expander.getExpandedNode(oldValue);
+                if (expandedNode != null) getChildren().remove(expandedNode);
+            }
+        });
+    }
+
+    /**
+     * Create the expanded content node that should represent the current table row.
+     *
+     * If the expanded content node is not currently in the children list of the TableRow it is automatically added.
+     *
+     * @return The expanded content Node
+     */
+    private Node getContent() {
+        Node node = expander.getOrCreateExpandedNode(tableRow);
+        if (!getChildren().contains(node)) getChildren().add(node);
+        return node;
+    }
+
+    /**
+     * Check if the current node is expanded. This is done by checking that there is an item for the current row,
+     * and that the expanded property for the row is true.
+     *
+     * @return A boolean indicating the expanded state of this row
+     */
+    private Boolean isExpanded() {
+        return getSkinnable().getItem() != null && expander.getCellData(getSkinnable().getIndex());
+    }
+
+    /**
+     * Add the preferred height of the expanded Node whenever the expanded flag is true.
+     *
+     * @return The preferred height of the TableRow, appended with the preferred height of the expanded node
+     * if this row is currently expanded.
+     */
+    @Override
+    protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        tableRowPrefHeight = super.computePrefHeight(width, topInset, rightInset, bottomInset, leftInset);
+        return isExpanded() ? tableRowPrefHeight + getContent().prefHeight(width) : tableRowPrefHeight;
+    }
+
+    /**
+     * Lay out the columns of the TableRow, then add the expanded content node below if this row is currently expanded.
+     */
+    @Override
+    protected void layoutChildren(double x, double y, double w, double h) {
+        super.layoutChildren(x, y, w, h);
+        if (isExpanded()) getContent().resizeRelocate(0.0, tableRowPrefHeight, w, h - tableRowPrefHeight);
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/GridCellSkin.java b/src/impl/org/controlsfx/skin/GridCellSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..db10ea75597e12f44f9f5f5105760102dad71da8
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/GridCellSkin.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import java.util.Collections;
+
+import org.controlsfx.control.GridCell;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.skin.CellSkinBase;
+
+public class GridCellSkin<T> extends CellSkinBase<GridCell<T>, BehaviorBase<GridCell<T>>> {
+
+    public GridCellSkin(GridCell<T> control) {
+        super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
+    }
+
+}
diff --git a/src/impl/org/controlsfx/skin/GridRow.java b/src/impl/org/controlsfx/skin/GridRow.java
new file mode 100644
index 0000000000000000000000000000000000000000..548ee8e22adac8d761f4f2391a9a5453cc82d3e9
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/GridRow.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import org.controlsfx.control.GridView;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.scene.control.IndexedCell;
+import javafx.scene.control.Skin;
+
+/**
+ * A GridRow is a container for {@link GridCell}, and represents a single
+ * row inside a {@link GridView}.
+ */
+class GridRow<T> extends IndexedCell<T>{
+
+
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/	
+
+    /**
+     * 
+     */
+    public GridRow() {
+        super();
+        getStyleClass().add("grid-row"); //$NON-NLS-1$
+
+        // we need to do this (or something similar) to allow for mouse wheel
+        // scrolling, as the GridRow has to report that it is non-empty (which
+        // is the second argument going into updateItem).
+        indexProperty().addListener(new InvalidationListener() {
+            @Override public void invalidated(Observable observable) {
+                updateItem(null, getIndex() == -1);
+            }
+        });
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new GridRowSkin<>(this);
+    }
+
+
+
+    /**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+
+    /**
+     * The {@link GridView} that this GridRow exists within.
+     */
+    public SimpleObjectProperty<GridView<T>> gridViewProperty() {
+        return gridView;
+    }
+    private final SimpleObjectProperty<GridView<T>> gridView = 
+            new SimpleObjectProperty<>(this, "gridView"); //$NON-NLS-1$
+    
+    /**
+     * Sets the {@link GridView} that this GridRow exists within.
+     */
+    public final void updateGridView(GridView<T> gridView) {
+        this.gridView.set(gridView);
+    }
+    
+    /**
+     * Returns the {@link GridView} that this GridRow exists within.
+     */
+    public GridView<T> getGridView() {
+        return gridView.get();
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/GridRowSkin.java b/src/impl/org/controlsfx/skin/GridRowSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b03097a7b329c007da3af44217e5cd80d9f2ef4
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/GridRowSkin.java
@@ -0,0 +1,179 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import java.util.Collections;
+
+import javafx.scene.Node;
+
+import org.controlsfx.control.GridCell;
+import org.controlsfx.control.GridView;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.skin.CellSkinBase;
+
+public class GridRowSkin<T> extends CellSkinBase<GridRow<T>, BehaviorBase<GridRow<T>>> {
+
+    public GridRowSkin(GridRow<T> control) {
+        super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
+
+        // Remove any children before creating cells (by default a LabeledText exist and we don't need it)
+        getChildren().clear();
+        updateCells();
+        
+        registerChangeListener(getSkinnable().indexProperty(), "INDEX"); //$NON-NLS-1$
+        registerChangeListener(getSkinnable().widthProperty(), "WIDTH"); //$NON-NLS-1$
+        registerChangeListener(getSkinnable().heightProperty(), "HEIGHT"); //$NON-NLS-1$
+    }
+    
+    @Override protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+        
+        if ("INDEX".equals(p)) { //$NON-NLS-1$
+            updateCells();
+        } else if ("WIDTH".equals(p)) { //$NON-NLS-1$
+            updateCells();
+        } else if ("HEIGHT".equals(p)) { //$NON-NLS-1$
+            updateCells();
+        }
+    }
+
+    /**
+     *  Returns a cell element at a desired index
+     *  @param index The index of the wanted cell element
+     *  @return Cell element if exist else null
+     */
+    @SuppressWarnings("unchecked")
+	public GridCell<T> getCellAtIndex(int index) {
+        if( index < getChildren().size() ) {
+            return (GridCell<T>)getChildren().get(index);
+        }
+        return null;
+    }
+        
+    /**
+     *  Update all cells
+     *  <p>Cells are only created when needed and re-used when possible.</p>
+     */
+    public void updateCells() {
+        int rowIndex = getSkinnable().getIndex();
+        if (rowIndex >= 0) {
+            GridView<T> gridView = getSkinnable().getGridView();
+            int maxCellsInRow = ((GridViewSkin<?>)gridView.getSkin()).computeMaxCellsInRow();
+            int totalCellsInGrid = gridView.getItems().size();
+            int startCellIndex = rowIndex * maxCellsInRow;
+            int endCellIndex = startCellIndex + maxCellsInRow - 1;
+            int cacheIndex = 0;
+
+            for (int cellIndex = startCellIndex; cellIndex <= endCellIndex; cellIndex++, cacheIndex++) {
+                if (cellIndex < totalCellsInGrid) {
+                    // Check if we can re-use a cell at this index or create a new one
+                    GridCell<T> cell = getCellAtIndex(cacheIndex);
+                    if( cell == null ) {
+                        cell = createCell();
+                        getChildren().add(cell);
+                    }
+                    cell.updateIndex(-1);
+                    cell.updateIndex(cellIndex);
+                }
+                // we are going out of bounds -> exist the loop
+                else { break; }
+            }
+            
+            // In case we are re-using a row that previously had more cells than
+            // this one, we need to remove the extra cells that remain
+            getChildren().remove(cacheIndex, getChildren().size());
+        }
+    }
+
+    private GridCell<T> createCell() {
+        GridView<T> gridView = getSkinnable().gridViewProperty().get();
+        GridCell<T> cell;
+        if (gridView.getCellFactory() != null) {
+            cell = gridView.getCellFactory().call(gridView);
+        } else {
+            cell = createDefaultCellImpl();
+        }
+        cell.updateGridView(gridView);
+        return cell;
+    }
+
+    private GridCell<T> createDefaultCellImpl() {
+        return new GridCell<T>() {
+            @Override protected void updateItem(T item, boolean empty) {
+                super.updateItem(item, empty);
+                if(empty) {
+                    setText(""); //$NON-NLS-1$
+                } else {
+                    setText(item.toString());
+                }
+            }
+        };
+    }
+    
+    @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return super.computePrefHeight(width, topInset, rightInset, bottomInset, leftInset);
+    }
+
+    @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return Double.MAX_VALUE;
+    }
+
+    @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        GridView<T> gv = getSkinnable().gridViewProperty().get();
+        return gv.getCellHeight() + gv.getVerticalCellSpacing() * 2;
+    }
+
+    @Override protected void layoutChildren(double x, double y, double w, double h) {
+//        double currentWidth = getSkinnable().getWidth();
+        double cellWidth = getSkinnable().gridViewProperty().get().getCellWidth();
+        double cellHeight = getSkinnable().gridViewProperty().get().getCellHeight();
+        double horizontalCellSpacing = getSkinnable().gridViewProperty().get().getHorizontalCellSpacing();
+        double verticalCellSpacing = getSkinnable().gridViewProperty().get().getVerticalCellSpacing();
+
+        double xPos = 0;
+        double yPos = 0;
+
+        // This has been commented out as I removed the API from GridView until
+        // a use case was created.
+//        HPos currentHorizontalAlignment = getSkinnable().gridViewProperty().get().getHorizontalAlignment();
+//        if (currentHorizontalAlignment != null) {
+//            if (currentHorizontalAlignment.equals(HPos.CENTER)) {
+//                xPos = (currentWidth % computeCellWidth()) / 2;
+//            } else if (currentHorizontalAlignment.equals(HPos.RIGHT)) {
+//                xPos = currentWidth % computeCellWidth();
+//            }
+//        }
+
+        for (Node child : getChildren()) {
+            child.relocate(xPos + horizontalCellSpacing, yPos + verticalCellSpacing);
+            child.resize(cellWidth, cellHeight);
+            xPos = xPos + horizontalCellSpacing + cellWidth + horizontalCellSpacing;
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/GridViewSkin.java b/src/impl/org/controlsfx/skin/GridViewSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..8eea039df1e266c59923615cd2db6ec2cb3450e7
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/GridViewSkin.java
@@ -0,0 +1,230 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import java.util.Collections;
+
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.collections.WeakListChangeListener;
+import javafx.util.Callback;
+
+import org.controlsfx.control.GridView;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.skin.VirtualContainerBase;
+import com.sun.javafx.scene.control.skin.VirtualFlow;
+
+public class GridViewSkin<T> extends VirtualContainerBase<GridView<T>, BehaviorBase<GridView<T>>, GridRow<T>> {
+    
+    private final ListChangeListener<T> gridViewItemsListener = new ListChangeListener<T>() {
+        @Override public void onChanged(ListChangeListener.Change<? extends T> change) {
+            updateRowCount();
+            getSkinnable().requestLayout();
+        }
+    };
+
+    private final WeakListChangeListener<T> weakGridViewItemsListener = new WeakListChangeListener<>(gridViewItemsListener);
+
+    @SuppressWarnings("rawtypes")
+    public GridViewSkin(GridView<T> control) {
+        super(control, new BehaviorBase<>(control, Collections.<KeyBinding>emptyList()));
+        
+        updateGridViewItems();
+
+        flow.setId("virtual-flow"); //$NON-NLS-1$
+        flow.setPannable(false);
+        flow.setVertical(true);
+        flow.setFocusTraversable(getSkinnable().isFocusTraversable());
+        flow.setCreateCell(new Callback<VirtualFlow, GridRow<T>>() {
+            @Override public GridRow<T> call(VirtualFlow flow) {
+                return GridViewSkin.this.createCell();
+            }
+        });
+        getChildren().add(flow);
+
+        updateRowCount();
+
+        // Register listeners
+        registerChangeListener(control.itemsProperty(), "ITEMS"); //$NON-NLS-1$
+        registerChangeListener(control.cellFactoryProperty(), "CELL_FACTORY"); //$NON-NLS-1$
+        registerChangeListener(control.parentProperty(), "PARENT"); //$NON-NLS-1$
+        registerChangeListener(control.cellHeightProperty(), "CELL_HEIGHT"); //$NON-NLS-1$
+        registerChangeListener(control.cellWidthProperty(), "CELL_WIDTH"); //$NON-NLS-1$
+        registerChangeListener(control.horizontalCellSpacingProperty(), "HORIZONZAL_CELL_SPACING"); //$NON-NLS-1$
+        registerChangeListener(control.verticalCellSpacingProperty(), "VERTICAL_CELL_SPACING"); //$NON-NLS-1$
+        registerChangeListener(control.widthProperty(), "WIDTH_PROPERTY"); //$NON-NLS-1$
+        registerChangeListener(control.heightProperty(), "HEIGHT_PROPERTY"); //$NON-NLS-1$
+    }
+
+    @Override protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+        if (p == "ITEMS") { //$NON-NLS-1$
+            updateGridViewItems();
+        } else if (p == "CELL_FACTORY") { //$NON-NLS-1$
+            flow.recreateCells();
+        } else if (p == "CELL_HEIGHT") { //$NON-NLS-1$
+            flow.recreateCells();
+        } else if (p == "CELL_WIDTH") { //$NON-NLS-1$
+            updateRowCount();
+            flow.recreateCells();
+        } else if (p == "HORIZONZAL_CELL_SPACING") { //$NON-NLS-1$
+            updateRowCount();
+            flow.recreateCells();
+        } else if (p == "VERTICAL_CELL_SPACING") { //$NON-NLS-1$
+            flow.recreateCells();
+        } else if (p == "PARENT") { //$NON-NLS-1$
+            if (getSkinnable().getParent() != null && getSkinnable().isVisible()) {
+                getSkinnable().requestLayout();
+            }
+        } else if (p == "WIDTH_PROPERTY" || p == "HEIGHT_PROPERTY") { //$NON-NLS-1$ //$NON-NLS-2$
+            updateRowCount();
+        }
+    }
+    
+    // Added by Fanis!!!
+    public VirtualFlow<GridRow<T>> getFlow() {
+    	return flow;
+    }
+
+    public void updateGridViewItems() {
+        if (getSkinnable().getItems() != null) {
+            getSkinnable().getItems().removeListener(weakGridViewItemsListener);
+        }
+
+        if (getSkinnable().getItems() != null) {
+            getSkinnable().getItems().addListener(weakGridViewItemsListener);
+        }
+
+        updateRowCount();
+        flow.recreateCells();
+        getSkinnable().requestLayout();
+    }
+
+    @Override protected void updateRowCount() {
+        if (flow == null)
+            return;
+
+        int oldCount = flow.getCellCount();
+        int newCount = getItemCount();
+        
+        if (newCount != oldCount) {
+            flow.setCellCount(newCount);
+            flow.rebuildCells();
+        } else {
+            flow.reconfigureCells();
+        }
+        updateRows(newCount);
+    }
+
+    @Override protected void layoutChildren(double x, double y, double w, double h) {
+        double x1 = getSkinnable().getInsets().getLeft();
+        double y1 = getSkinnable().getInsets().getTop();
+        double w1 = getSkinnable().getWidth() - (getSkinnable().getInsets().getLeft() + getSkinnable().getInsets().getRight());
+        double h1 = getSkinnable().getHeight() - (getSkinnable().getInsets().getTop() + getSkinnable().getInsets().getBottom());
+
+        flow.resizeRelocate(x1, y1, w1, h1);
+    }
+
+    @Override public GridRow<T> createCell() {
+        GridRow<T> row = new GridRow<>();
+        row.updateGridView(getSkinnable());
+        return row;
+    }
+
+    /**
+     *  Returns the number of row needed to display the whole set of cells
+     *  @return GridView row count
+     */
+    @Override public int getItemCount() {
+        final ObservableList<?> items = getSkinnable().getItems();
+        // Fix for #98 : int division should be cast to get the result as
+        // double and ceiled to get the max int of it (as we are looking for
+        // the max number of necessary row)
+        return items == null ? 0 : (int)Math.ceil((double)items.size() / computeMaxCellsInRow());
+    }
+
+    /**
+     *  Returns the max number of cell per row
+     *  @return Max cell number per row 
+     */
+    public int computeMaxCellsInRow() {
+        return Math.max((int) Math.floor(computeRowWidth() / computeCellWidth()), 1);
+    }
+
+    /**
+     *  Returns the width of a row
+     *  (should be GridView.width - GridView.Scrollbar.width)
+     *  @return Computed width of a row 
+     */
+    protected double computeRowWidth() {
+        // Fix for #98 : width calculation should take the scrollbar size
+        // into account
+        
+        // TODO: need to figure out how to get the real scrollbar width and
+        // replace the 18 value
+        return getSkinnable().getWidth() - 18;
+    }
+
+    /**
+     *  Returns the width of a cell
+     *  @return Computed width of a cell 
+     */
+    protected double computeCellWidth() {
+        return getSkinnable().cellWidthProperty().doubleValue() + (getSkinnable().horizontalCellSpacingProperty().doubleValue() * 2);
+    }
+
+    protected void updateRows(int rowCount) {
+        for (int i = 0; i < rowCount; i++) {
+            GridRow<T> row = flow.getVisibleCell(i);
+            if (row != null) {
+                // FIXME hacky - need to better understand what this is about
+                row.updateIndex(-1);
+                row.updateIndex(i);
+            }
+        }
+    }
+
+    protected boolean areRowsVisible() {
+        if (flow == null)
+            return false;
+
+        if (flow.getFirstVisibleCell() == null)
+            return false;
+
+        if (flow.getLastVisibleCell() == null)
+            return false;
+
+        return true;
+    }
+    
+    @Override protected double computeMinHeight(double height, double topInset, double rightInset, double bottomInset,
+            double leftInset) {
+        return 0;
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/HiddenSidesPaneSkin.java b/src/impl/org/controlsfx/skin/HiddenSidesPaneSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd040bdf80b2b08f0547d440d51b6847c03663dc
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/HiddenSidesPaneSkin.java
@@ -0,0 +1,336 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import javafx.animation.Animation.Status;
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.Timeline;
+import javafx.beans.InvalidationListener;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.event.EventHandler;
+import javafx.geometry.Side;
+import javafx.scene.Node;
+import javafx.scene.control.SkinBase;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.StackPane;
+import javafx.scene.shape.Rectangle;
+import javafx.util.Duration;
+
+import org.controlsfx.control.HiddenSidesPane;
+
+public class HiddenSidesPaneSkin extends SkinBase<HiddenSidesPane> {
+
+    private final StackPane stackPane;
+    private final EventHandler<MouseEvent> exitedHandler;
+    private boolean mousePressed;
+
+    public HiddenSidesPaneSkin(HiddenSidesPane pane) {
+        super(pane);
+
+        exitedHandler = event -> {
+            if (isMouseEnabled() && getSkinnable().getPinnedSide() == null
+                    && !mousePressed) {
+                hide();
+            }
+        };
+
+        stackPane = new StackPane();
+        getChildren().add(stackPane);
+        updateStackPane();
+
+        InvalidationListener rebuildListener = observable -> updateStackPane();
+        pane.contentProperty().addListener(rebuildListener);
+        pane.topProperty().addListener(rebuildListener);
+        pane.rightProperty().addListener(rebuildListener);
+        pane.bottomProperty().addListener(rebuildListener);
+        pane.leftProperty().addListener(rebuildListener);
+
+        pane.addEventFilter(MouseEvent.MOUSE_MOVED, event -> {
+            if (isMouseEnabled() && getSkinnable().getPinnedSide() == null) {
+                Side side = getSide(event);
+                if (side != null) {
+                    show(side);
+                } else if (isMouseMovedOutsideSides(event)) {
+                    hide();
+                }
+            }
+        });
+
+        pane.addEventFilter(MouseEvent.MOUSE_EXITED, exitedHandler);
+
+        pane.addEventFilter(MouseEvent.MOUSE_PRESSED,
+                event -> mousePressed = true);
+
+        pane.addEventFilter(MouseEvent.MOUSE_RELEASED, event -> {
+            mousePressed = false;
+
+            if (isMouseEnabled() && getSkinnable().getPinnedSide() == null) {
+                Side side = getSide(event);
+                if (side != null) {
+                    show(side);
+                } else {
+                    hide();
+                }
+            }
+        });
+
+        for (Side side : Side.values()) {
+            visibility[side.ordinal()] = new SimpleDoubleProperty(0);
+            visibility[side.ordinal()].addListener(observable -> getSkinnable()
+                    .requestLayout());
+        }
+
+        Side pinnedSide = getSkinnable().getPinnedSide();
+        if (pinnedSide != null) {
+        	show(pinnedSide);
+        }
+
+        pane.pinnedSideProperty().addListener(
+                observable -> show(getSkinnable().getPinnedSide()));
+
+        Rectangle clip = new Rectangle();
+        clip.setX(0);
+        clip.setY(0);
+        clip.widthProperty().bind(getSkinnable().widthProperty());
+        clip.heightProperty().bind(getSkinnable().heightProperty());
+
+        getSkinnable().setClip(clip);
+    }
+
+    private boolean isMouseMovedOutsideSides(MouseEvent event) {
+        if (getSkinnable().getLeft() != null
+                && getSkinnable().getLeft().getBoundsInParent()
+                        .contains(event.getX(), event.getY())) {
+            return false;
+        }
+
+        if (getSkinnable().getTop() != null
+                && getSkinnable().getTop().getBoundsInParent()
+                        .contains(event.getX(), event.getY())) {
+            return false;
+        }
+
+        if (getSkinnable().getRight() != null
+                && getSkinnable().getRight().getBoundsInParent()
+                        .contains(event.getX(), event.getY())) {
+            return false;
+        }
+
+        if (getSkinnable().getBottom() != null
+                && getSkinnable().getBottom().getBoundsInParent()
+                        .contains(event.getX(), event.getY())) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean isMouseEnabled() {
+        return getSkinnable().getTriggerDistance() > 0;
+    }
+
+    private Side getSide(MouseEvent evt) {
+        if (stackPane.getBoundsInLocal().contains(evt.getX(), evt.getY())) {
+            double trigger = getSkinnable().getTriggerDistance();
+            if (evt.getX() <= trigger) {
+                return Side.LEFT;
+            } else if (evt.getX() > getSkinnable().getWidth() - trigger) {
+                return Side.RIGHT;
+            } else if (evt.getY() <= trigger) {
+                return Side.TOP;
+            } else if (evt.getY() > getSkinnable().getHeight() - trigger) {
+                return Side.BOTTOM;
+            }
+        }
+
+        return null;
+    }
+
+    private DoubleProperty[] visibility = new SimpleDoubleProperty[Side
+            .values().length];
+
+    private Timeline showTimeline;
+
+    private void show(Side side) {
+        if (hideTimeline != null) {
+            hideTimeline.stop();
+        }
+
+        if (showTimeline != null && showTimeline.getStatus() == Status.RUNNING) {
+            return;
+        }
+
+        KeyValue[] keyValues = new KeyValue[Side.values().length];
+        for (Side s : Side.values()) {
+            keyValues[s.ordinal()] = new KeyValue(visibility[s.ordinal()],
+                    s.equals(side) ? 1 : 0);
+        }
+
+        Duration delay = getSkinnable().getAnimationDelay() != null ? getSkinnable()
+                .getAnimationDelay() : Duration.millis(300);
+        Duration duration = getSkinnable().getAnimationDuration() != null ? getSkinnable()
+                .getAnimationDuration() : Duration.millis(200);
+
+        KeyFrame keyFrame = new KeyFrame(duration, keyValues);
+        showTimeline = new Timeline(keyFrame);
+        showTimeline.setDelay(delay);
+        showTimeline.play();
+    }
+
+    private Timeline hideTimeline;
+
+    private void hide() {
+        if (showTimeline != null) {
+            showTimeline.stop();
+        }
+
+        if (hideTimeline != null && hideTimeline.getStatus() == Status.RUNNING) {
+            return;
+        }
+
+        boolean sideVisible = false;
+        for (Side side : Side.values()) {
+            if (visibility[side.ordinal()].get() > 0) {
+                sideVisible = true;
+                break;
+            }
+        }
+
+        // nothing to do here
+        if (!sideVisible) {
+            return;
+        }
+
+        KeyValue[] keyValues = new KeyValue[Side.values().length];
+        for (Side side : Side.values()) {
+            keyValues[side.ordinal()] = new KeyValue(
+                    visibility[side.ordinal()], 0);
+        }
+
+        Duration delay = getSkinnable().getAnimationDelay() != null ? getSkinnable()
+                .getAnimationDelay() : Duration.millis(300);
+        Duration duration = getSkinnable().getAnimationDuration() != null ? getSkinnable()
+                .getAnimationDuration() : Duration.millis(200);
+
+        KeyFrame keyFrame = new KeyFrame(duration, keyValues);
+        hideTimeline = new Timeline(keyFrame);
+        hideTimeline.setDelay(delay);
+        hideTimeline.play();
+    }
+
+    private void updateStackPane() {
+        stackPane.getChildren().clear();
+
+        if (getSkinnable().getContent() != null) {
+            stackPane.getChildren().add(getSkinnable().getContent());
+        }
+        if (getSkinnable().getTop() != null) {
+            stackPane.getChildren().add(getSkinnable().getTop());
+            getSkinnable().getTop().setManaged(false);
+            getSkinnable().getTop().removeEventFilter(MouseEvent.MOUSE_EXITED,
+                    exitedHandler);
+            getSkinnable().getTop().addEventFilter(MouseEvent.MOUSE_EXITED,
+                    exitedHandler);
+        }
+        if (getSkinnable().getRight() != null) {
+            stackPane.getChildren().add(getSkinnable().getRight());
+            getSkinnable().getRight().setManaged(false);
+            getSkinnable().getRight().removeEventFilter(
+                    MouseEvent.MOUSE_EXITED, exitedHandler);
+            getSkinnable().getRight().addEventFilter(MouseEvent.MOUSE_EXITED,
+                    exitedHandler);
+        }
+        if (getSkinnable().getBottom() != null) {
+            stackPane.getChildren().add(getSkinnable().getBottom());
+            getSkinnable().getBottom().setManaged(false);
+            getSkinnable().getBottom().removeEventFilter(
+                    MouseEvent.MOUSE_EXITED, exitedHandler);
+            getSkinnable().getBottom().addEventFilter(MouseEvent.MOUSE_EXITED,
+                    exitedHandler);
+        }
+        if (getSkinnable().getLeft() != null) {
+            stackPane.getChildren().add(getSkinnable().getLeft());
+            getSkinnable().getLeft().setManaged(false);
+            getSkinnable().getLeft().removeEventFilter(MouseEvent.MOUSE_EXITED,
+                    exitedHandler);
+            getSkinnable().getLeft().addEventFilter(MouseEvent.MOUSE_EXITED,
+                    exitedHandler);
+        }
+    }
+
+    @Override
+    protected void layoutChildren(double contentX, double contentY,
+            double contentWidth, double contentHeight) {
+
+        /*
+         * Layout the stackpane in a normal way (equals
+         * "lay out the content node", the only managed node)
+         */
+        super.layoutChildren(contentX, contentY, contentWidth, contentHeight);
+
+        // layout the unmanaged side nodes
+
+        Node bottom = getSkinnable().getBottom();
+        if (bottom != null) {
+            double prefHeight = bottom.prefHeight(-1);
+            double offset = prefHeight
+                    * visibility[Side.BOTTOM.ordinal()].get();
+            bottom.resizeRelocate(contentX, contentY + contentHeight - offset,
+                    contentWidth, prefHeight);
+            bottom.setVisible(visibility[Side.BOTTOM.ordinal()].get() > 0);
+        }
+
+        Node left = getSkinnable().getLeft();
+        if (left != null) {
+            double prefWidth = left.prefWidth(-1);
+            double offset = prefWidth * visibility[Side.LEFT.ordinal()].get();
+            left.resizeRelocate(contentX - (prefWidth - offset), contentY,
+                    prefWidth, contentHeight);
+            left.setVisible(visibility[Side.LEFT.ordinal()].get() > 0);
+        }
+
+        Node right = getSkinnable().getRight();
+        if (right != null) {
+            double prefWidth = right.prefWidth(-1);
+            double offset = prefWidth * visibility[Side.RIGHT.ordinal()].get();
+            right.resizeRelocate(contentX + contentWidth - offset, contentY,
+                    prefWidth, contentHeight);
+            right.setVisible(visibility[Side.RIGHT.ordinal()].get() > 0);
+        }
+
+        Node top = getSkinnable().getTop();
+        if (top != null) {
+            double prefHeight = top.prefHeight(-1);
+            double offset = prefHeight * visibility[Side.TOP.ordinal()].get();
+            top.resizeRelocate(contentX, contentY - (prefHeight - offset),
+                    contentWidth, prefHeight);
+            top.setVisible(visibility[Side.TOP.ordinal()].get() > 0);
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/HyperlinkLabelSkin.java b/src/impl/org/controlsfx/skin/HyperlinkLabelSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..10e668148191b5fe04a4ddbab07e5fff461a0470
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/HyperlinkLabelSkin.java
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.scene.Node;
+import javafx.scene.control.Hyperlink;
+import javafx.scene.control.Label;
+import javafx.scene.text.Text;
+import javafx.scene.text.TextFlow;
+
+import org.controlsfx.control.HyperlinkLabel;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+
+public class HyperlinkLabelSkin extends BehaviorSkinBase<HyperlinkLabel, BehaviorBase<HyperlinkLabel>> {
+    
+    /***************************************************************************
+     * 
+     * Static fields
+     * 
+     **************************************************************************/
+    
+    // The strings used to delimit the hyperlinks
+    private static final String HYPERLINK_START = "["; //$NON-NLS-1$
+    private static final String HYPERLINK_END = "]"; //$NON-NLS-1$
+    
+    
+    
+    /***************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+    private final TextFlow textFlow;
+    private final EventHandler<ActionEvent> eventHandler = new EventHandler<ActionEvent>() {
+        @Override public void handle(final ActionEvent event) {
+            EventHandler<ActionEvent> onActionHandler = getSkinnable().getOnAction();
+            if (onActionHandler != null) {
+                onActionHandler.handle(event);
+            }
+        }
+    };
+    
+    
+
+    /***************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    public HyperlinkLabelSkin(HyperlinkLabel control) {
+        super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
+        
+        this.textFlow = new TextFlow();
+        getChildren().add(textFlow);
+        updateText();
+        
+        registerChangeListener(control.textProperty(), "TEXT"); //$NON-NLS-1$
+    }
+
+    
+    
+    /***************************************************************************
+     * 
+     * Implementation
+     * 
+     **************************************************************************/
+    
+    @Override protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+        
+        if (p == "TEXT") { //$NON-NLS-1$
+            updateText();
+        }
+    }
+    
+    // splits up the string into Text and Hyperlink nodes, and places them
+    // into a TextFlow instance
+    private void updateText() {
+        final String text = getSkinnable().getText();
+        
+        if (text == null || text.isEmpty()) {
+            textFlow.getChildren().clear();
+            return;
+        }
+        
+        // parse the text and put it into an array list
+        final List<Node> nodes = new ArrayList<>();
+        
+        int start = 0;
+        final int textLength = text.length();
+        while (start != -1 && start < textLength) {
+            int startPos = text.indexOf(HYPERLINK_START, start);
+            int endPos = text.indexOf(HYPERLINK_END, startPos);
+            
+            // if the startPos is -1, there are no more hyperlinks...
+            if (startPos == -1 || endPos == -1) {
+                if (textLength > start) {
+                    // ...but there is still text to turn into one last label
+                    Label label = new Label(text.substring(start));
+                    nodes.add(label);
+                    break;
+                }
+            }
+            
+            // firstly, create a label from start to startPos
+            Text label = new Text(text.substring(start, startPos));
+            nodes.add(label);
+            
+            // if endPos is greater than startPos, create a hyperlink
+            Hyperlink hyperlink = new Hyperlink(text.substring(startPos + 1, endPos));
+            hyperlink.setPadding(new Insets(0, 0, 0, 0));
+            hyperlink.setOnAction(eventHandler);
+            nodes.add(hyperlink);
+            
+            start = endPos + 1;
+        }
+        
+        textFlow.getChildren().setAll(nodes);
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/InfoOverlaySkin.java b/src/impl/org/controlsfx/skin/InfoOverlaySkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..71bc6ad2aad399d22f74328e499dcca84827d260
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/InfoOverlaySkin.java
@@ -0,0 +1,248 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package impl.org.controlsfx.skin;
+
+import java.util.Collections;
+
+import javafx.animation.Animation.Status;
+import javafx.animation.Interpolator;
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.Timeline;
+import javafx.beans.binding.Bindings;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.EventHandler;
+import javafx.geometry.HPos;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.geometry.VPos;
+import javafx.scene.Cursor;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.HBox;
+import javafx.util.Duration;
+
+import org.controlsfx.control.InfoOverlay;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+
+public class InfoOverlaySkin extends BehaviorSkinBase<InfoOverlay, BehaviorBase<InfoOverlay>> {
+    
+    private final ImageView EXPAND_IMAGE = new ImageView(new Image(InfoOverlay.class.getResource("expand.png").toExternalForm())); //$NON-NLS-1$
+    private final ImageView COLLAPSE_IMAGE = new ImageView(new Image(InfoOverlay.class.getResource("collapse.png").toExternalForm())); //$NON-NLS-1$
+    
+    private static final Duration TRANSITION_DURATION = new Duration(350.0);
+
+    private Node content;
+    private Label infoLabel;
+    private HBox infoPanel;
+    private ToggleButton expandCollapseButton;
+
+    // animation support
+    private Timeline timeline;
+    private DoubleProperty transition = new SimpleDoubleProperty(this, "transition", 0.0) { //$NON-NLS-1$
+        @Override protected void invalidated() {
+            getSkinnable().requestLayout();
+        }
+    };
+
+    public InfoOverlaySkin(final InfoOverlay control) {
+        super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
+
+        // content
+        content = control.getContent();
+        control.hoverProperty().addListener(new ChangeListener<Boolean>() {
+            @Override public void changed(ObservableValue<? extends Boolean> o, Boolean wasHover, Boolean isHover) {
+                if (control.isShowOnHover()) {
+                    if ((isHover && ! isExpanded()) || (!isHover && isExpanded())) {
+                        doToggle();
+                    }
+                }
+            }
+        });
+
+        // text
+        infoLabel = new Label();
+        infoLabel.setWrapText(true);
+        infoLabel.setAlignment(Pos.TOP_LEFT);
+        infoLabel.getStyleClass().add("info"); //$NON-NLS-1$
+        infoLabel.textProperty().bind(control.textProperty());
+
+        // button to expand / collapse the info overlay
+        expandCollapseButton = new ToggleButton();
+        expandCollapseButton.setMouseTransparent(true);
+        expandCollapseButton.visibleProperty().bind(Bindings.not(control.showOnHoverProperty()));
+        expandCollapseButton.managedProperty().bind(Bindings.not(control.showOnHoverProperty()));
+        updateToggleButton();
+
+        // container for the info overlay and the button
+        infoPanel = new HBox(infoLabel, expandCollapseButton);
+        infoPanel.setAlignment(Pos.TOP_LEFT);
+        infoPanel.setFillHeight(true);
+        infoPanel.getStyleClass().add("info-panel"); //$NON-NLS-1$
+        infoPanel.setCursor(Cursor.HAND);
+        infoPanel.setOnMouseClicked(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent e) {
+                if (! control.isShowOnHover()) {
+                    doToggle();
+                }
+            }
+        });
+
+        // adding everything to the scenegraph
+        getChildren().addAll(content, infoPanel);
+        
+        registerChangeListener(control.contentProperty(), "CONTENT"); //$NON-NLS-1$
+    }
+    
+    @Override protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+        
+        if ("CONTENT".equals(p)) { //$NON-NLS-1$
+            getChildren().remove(0);
+            getChildren().add(0, getSkinnable().getContent());
+            getSkinnable().requestLayout();
+        }
+    }
+    
+    private void doToggle() {
+        // do animation to show / hide the info panel
+        expandCollapseButton.setSelected(!expandCollapseButton.isSelected());
+        toggleInfoPanel();
+        updateToggleButton();
+    }
+    
+    private boolean isExpanded() {
+        return expandCollapseButton.isSelected();
+    }
+
+    @Override
+    protected void layoutChildren(double contentX, double contentY, double contentWidth, double contentHeight) {
+        final double contentPrefHeight = content.prefHeight(contentWidth);
+        
+        // we calculate the pref width of the expand/collapse button. We will
+        // ensure that the button does not get smaller than this.
+        final double toggleButtonPrefWidth = expandCollapseButton.prefWidth(-1);
+        expandCollapseButton.setMinWidth(toggleButtonPrefWidth);
+
+        // All remaining width goes to the info label
+        final Insets infoPanelPadding = infoPanel.getPadding();
+        final double infoLabelWidth = snapSize(contentWidth - toggleButtonPrefWidth - 
+                infoPanelPadding.getLeft() - infoPanelPadding.getRight());
+
+        // we then can work out the necessary height for the info panel, based on
+        // whether it is expanded or not, and given the current state of the animation.
+        final double prefInfoPanelHeight = (snapSize(infoLabel.prefHeight(infoLabelWidth)) +
+                snapSpace(infoPanel.getPadding().getTop()) +
+                snapSpace(infoPanel.getPadding().getBottom())) *
+                transition.get();
+
+        infoLabel.setMaxWidth(infoLabelWidth);
+        infoLabel.setMaxHeight(prefInfoPanelHeight);
+
+        // position the imageView
+        layoutInArea(content, contentX, contentY,
+                                contentWidth, contentHeight, -1, HPos.CENTER, VPos.TOP);
+        
+        // position the infoPanel (the HBox consisting of the Label and ToggleButton)
+        layoutInArea(infoPanel, contentX, snapPosition(contentPrefHeight - prefInfoPanelHeight),
+                                contentWidth, prefInfoPanelHeight, 0, HPos.CENTER, VPos.BOTTOM);
+    }
+
+    private void updateToggleButton() {
+        if (expandCollapseButton.isSelected()) {
+            expandCollapseButton.getStyleClass().setAll("collapse-button"); //$NON-NLS-1$
+            expandCollapseButton.setGraphic(COLLAPSE_IMAGE);
+        } else {
+            expandCollapseButton.getStyleClass().setAll("expand-button"); //$NON-NLS-1$
+            expandCollapseButton.setGraphic(EXPAND_IMAGE);
+        }
+    }
+    
+    @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        double insets = topInset + bottomInset;
+        return insets + (content == null ? 0 : content.prefHeight(width));
+    }
+    
+    @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        double insets = leftInset + rightInset;
+        return insets + (content == null ? 0 : content.prefWidth(height));
+    }
+    
+    @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return computePrefHeight(width, topInset, rightInset, bottomInset, leftInset);
+    }
+    
+    @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return computePrefWidth(height, topInset, rightInset, bottomInset, leftInset);
+    }
+    
+    private void toggleInfoPanel() {
+        // animate!
+        // The best way I know how is to transition a number between 0.0 and 1.0
+        // over a set duration, and have this request layout as it goes. Then,
+        // use this value and multiply it against the actualInfoPanelHeight
+        // variable in layoutChildren - this will give a nice smooth animation.
+        if (content == null) {
+            return;
+        }
+
+        Duration duration;
+        if (timeline != null && (timeline.getStatus() != Status.STOPPED)) {
+            duration = timeline.getCurrentTime();
+            timeline.stop();
+        } else {
+            duration = TRANSITION_DURATION;
+        }
+
+        timeline = new Timeline();
+        timeline.setCycleCount(1);
+
+        KeyFrame k1, k2;
+
+        if (isExpanded()) {
+            k1 = new KeyFrame(Duration.ZERO, new KeyValue(transition, 0));
+            k2 = new KeyFrame(duration,new KeyValue(transition, 1, Interpolator.LINEAR));
+        } else {
+            k1 = new KeyFrame(Duration.ZERO, new KeyValue(transition, 1));
+            k2 = new KeyFrame(duration, new KeyValue(transition, 0, Interpolator.LINEAR));
+        }
+
+        timeline.getKeyFrames().setAll(k1, k2);
+        timeline.play();
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/ListSelectionViewSkin.java b/src/impl/org/controlsfx/skin/ListSelectionViewSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..376fac01f7ae65508f527bde48e263d81283032f
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/ListSelectionViewSkin.java
@@ -0,0 +1,474 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import static java.util.Objects.requireNonNull;
+import static javafx.scene.control.SelectionMode.MULTIPLE;
+import static javafx.scene.input.MouseEvent.MOUSE_CLICKED;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.binding.Bindings;
+import javafx.geometry.Orientation;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.ListView;
+import javafx.scene.control.SkinBase;
+import javafx.scene.input.MouseButton;
+import javafx.scene.layout.ColumnConstraints;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.RowConstraints;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+
+import org.controlsfx.control.ListSelectionView;
+import org.controlsfx.glyphfont.FontAwesome;
+
+public class ListSelectionViewSkin<T> extends SkinBase<ListSelectionView<T>> {
+
+    private GridPane gridPane;
+    private final HBox horizontalButtonBox;
+    private final VBox verticalButtonBox;
+    private Button moveToTarget;
+    private Button moveToTargetAll;
+    private Button moveToSourceAll;
+    private Button moveToSource;
+    private ListView<T> sourceListView;
+    private ListView<T> targetListView;
+
+    public ListSelectionViewSkin(ListSelectionView<T> view) {
+        super(view);
+
+        sourceListView = requireNonNull(createSourceListView(),
+                "source list view can not be null");
+        sourceListView.setId("source-list-view");
+        sourceListView.setItems(view.getSourceItems());
+
+        targetListView = requireNonNull(createTargetListView(),
+                "target list view can not be null");
+        targetListView.setId("target-list-view");
+        targetListView.setItems(view.getTargetItems());
+
+        sourceListView.cellFactoryProperty().bind(view.cellFactoryProperty());
+        targetListView.cellFactoryProperty().bind(view.cellFactoryProperty());
+
+        gridPane = createGridPane();
+        horizontalButtonBox = createHorizontalButtonBox();
+        verticalButtonBox = createVerticalButtonBox();
+
+        getChildren().add(gridPane);
+
+        InvalidationListener updateListener = o -> updateView();
+
+        view.sourceHeaderProperty().addListener(updateListener);
+        view.sourceFooterProperty().addListener(updateListener);
+        view.targetHeaderProperty().addListener(updateListener);
+        view.targetFooterProperty().addListener(updateListener);
+
+        updateView();
+
+        getSourceListView().addEventHandler(
+                MOUSE_CLICKED,
+                event -> {
+                    if (event.getButton() == MouseButton.PRIMARY
+                            && event.getClickCount() == 2) {
+                        moveToTarget();
+                    }
+                });
+
+        getTargetListView().addEventHandler(
+                MOUSE_CLICKED,
+                event -> {
+                    if (event.getButton() == MouseButton.PRIMARY
+                            && event.getClickCount() == 2) {
+                        moveToSource();
+                    }
+                });
+        
+        view.orientationProperty().addListener(observable -> updateView());
+    }
+
+    private GridPane createGridPane() {
+        GridPane gridPane = new GridPane();
+        gridPane.getStyleClass().add("grid-pane");
+
+        return gridPane;
+    }
+
+    // Constraints used when view's orientation is HORIZONTAL
+    private void setHorizontalViewContraints() {
+        gridPane.getColumnConstraints().clear();
+        gridPane.getRowConstraints().clear();
+    
+        ColumnConstraints col1 = new ColumnConstraints();
+
+        col1.setFillWidth(true);
+        col1.setHgrow(Priority.ALWAYS);
+        col1.setMaxWidth(Double.MAX_VALUE);
+        col1.setPrefWidth(200);
+
+        ColumnConstraints col2 = new ColumnConstraints();
+        col2.setFillWidth(true);
+        col2.setHgrow(Priority.NEVER);
+
+        ColumnConstraints col3 = new ColumnConstraints();
+        col3.setFillWidth(true);
+        col3.setHgrow(Priority.ALWAYS);
+        col3.setMaxWidth(Double.MAX_VALUE);
+        col3.setPrefWidth(200);
+
+        gridPane.getColumnConstraints().addAll(col1, col2, col3);
+
+        RowConstraints row1 = new RowConstraints();
+        row1.setFillHeight(true);
+        row1.setVgrow(Priority.NEVER);
+
+        RowConstraints row2 = new RowConstraints();
+        row2.setMaxHeight(Double.MAX_VALUE);
+        row2.setPrefHeight(200);
+        row2.setVgrow(Priority.ALWAYS);
+
+        RowConstraints row3 = new RowConstraints();
+        row3.setFillHeight(true);
+        row3.setVgrow(Priority.NEVER);
+
+        gridPane.getRowConstraints().addAll(row1, row2, row3);
+    }
+
+    // Constraints used when view's orientation is VERTICAL
+    private void setVerticalViewContraints() {
+        gridPane.getColumnConstraints().clear();
+        gridPane.getRowConstraints().clear();
+    
+        ColumnConstraints col1 = new ColumnConstraints();
+
+        col1.setFillWidth(true);
+        col1.setHgrow(Priority.ALWAYS);
+        col1.setMaxWidth(Double.MAX_VALUE);
+        col1.setPrefWidth(200);
+
+        gridPane.getColumnConstraints().addAll(col1);
+
+        RowConstraints row1 = new RowConstraints();
+        row1.setFillHeight(true);
+        row1.setVgrow(Priority.NEVER);
+
+        RowConstraints row2 = new RowConstraints();
+        row2.setMaxHeight(Double.MAX_VALUE);
+        row2.setPrefHeight(200);
+        row2.setVgrow(Priority.ALWAYS);
+
+        RowConstraints row3 = new RowConstraints();
+        row3.setFillHeight(true);
+        row3.setVgrow(Priority.NEVER);
+        
+        RowConstraints row4 = new RowConstraints();
+        row4.setFillHeight(true);
+        row4.setVgrow(Priority.NEVER);
+        
+        RowConstraints row5 = new RowConstraints();
+        row5.setFillHeight(true);
+        row5.setVgrow(Priority.NEVER);
+
+        RowConstraints row6 = new RowConstraints();
+        row6.setMaxHeight(Double.MAX_VALUE);
+        row6.setPrefHeight(200);
+        row6.setVgrow(Priority.ALWAYS);
+
+        RowConstraints row7 = new RowConstraints();
+        row7.setFillHeight(true);
+        row7.setVgrow(Priority.NEVER);
+        
+
+        gridPane.getRowConstraints().addAll(row1, row2, row3, row4, row5, row6, row7);
+    }
+
+    // Used when view's orientation is HORIZONTAL
+    private VBox createVerticalButtonBox() {
+        VBox box = new VBox(5);
+        box.setFillWidth(true);
+
+        FontAwesome fontAwesome = new FontAwesome();
+        moveToTarget = new Button("",
+                fontAwesome.create(FontAwesome.Glyph.ANGLE_RIGHT));
+        moveToTargetAll = new Button("",
+                fontAwesome.create(FontAwesome.Glyph.ANGLE_DOUBLE_RIGHT));
+
+        moveToSource = new Button("",
+                fontAwesome.create(FontAwesome.Glyph.ANGLE_LEFT));
+        moveToSourceAll = new Button("",
+                fontAwesome.create(FontAwesome.Glyph.ANGLE_DOUBLE_LEFT));
+
+        updateButtons();
+        
+        box.getChildren().addAll(moveToTarget, moveToTargetAll, moveToSource,
+                moveToSourceAll);
+
+        return box;
+    }
+
+    // Used when view's orientation is VERTICAL
+    private HBox createHorizontalButtonBox() {
+        HBox box = new HBox(5);
+        box.setFillHeight(true);
+
+        FontAwesome fontAwesome = new FontAwesome();
+        moveToTarget = new Button("",
+                fontAwesome.create(FontAwesome.Glyph.ANGLE_DOWN));
+        moveToTargetAll = new Button("",
+                fontAwesome.create(FontAwesome.Glyph.ANGLE_DOUBLE_DOWN));
+
+        moveToSource = new Button("",
+                fontAwesome.create(FontAwesome.Glyph.ANGLE_UP));
+        moveToSourceAll = new Button("",
+                fontAwesome.create(FontAwesome.Glyph.ANGLE_DOUBLE_UP));
+
+        updateButtons();
+        
+        box.getChildren().addAll(moveToTarget, moveToTargetAll, moveToSource,
+                moveToSourceAll);
+
+        return box;
+    }
+
+    private void updateButtons() {
+        
+        moveToTarget.getStyleClass().add("move-to-target-button");
+        moveToTargetAll.getStyleClass().add("move-to-target-all-button");
+        moveToSource.getStyleClass().add("move-to-source-button");
+        moveToSourceAll.getStyleClass().add("move-to-source-all-button");
+
+        moveToTarget.setMaxWidth(Double.MAX_VALUE);
+        moveToTargetAll.setMaxWidth(Double.MAX_VALUE);
+        moveToSource.setMaxWidth(Double.MAX_VALUE);
+        moveToSourceAll.setMaxWidth(Double.MAX_VALUE);
+
+        getSourceListView().itemsProperty().addListener(
+                it -> bindMoveAllButtonsToDataModel());
+
+        getTargetListView().itemsProperty().addListener(
+                it -> bindMoveAllButtonsToDataModel());
+
+        getSourceListView().selectionModelProperty().addListener(
+                it -> bindMoveButtonsToSelectionModel());
+
+        getTargetListView().selectionModelProperty().addListener(
+                it -> bindMoveButtonsToSelectionModel());
+
+        bindMoveButtonsToSelectionModel();
+        bindMoveAllButtonsToDataModel();
+
+        moveToTarget.setOnAction(evt -> moveToTarget());
+
+        moveToTargetAll.setOnAction(evt -> moveToTargetAll());
+
+        moveToSource.setOnAction(evt -> moveToSource());
+
+        moveToSourceAll.setOnAction(evt -> moveToSourceAll());
+    }
+    
+    private void bindMoveAllButtonsToDataModel() {
+        moveToTargetAll.disableProperty().bind(
+                Bindings.isEmpty(getSourceListView().getItems()));
+
+        moveToSourceAll.disableProperty().bind(
+                Bindings.isEmpty(getTargetListView().getItems()));
+    }
+
+    private void bindMoveButtonsToSelectionModel() {
+        moveToTarget.disableProperty().bind(
+                Bindings.isEmpty(getSourceListView().getSelectionModel()
+                        .getSelectedItems()));
+
+        moveToSource.disableProperty().bind(
+                Bindings.isEmpty(getTargetListView().getSelectionModel()
+                        .getSelectedItems()));
+    }
+
+    private void updateView() {
+        gridPane.getChildren().clear();
+
+        Node sourceHeader = getSkinnable().getSourceHeader();
+        Node targetHeader = getSkinnable().getTargetHeader();
+        Node sourceFooter = getSkinnable().getSourceFooter();
+        Node targetFooter = getSkinnable().getTargetFooter();
+
+        ListView<T> sourceList = getSourceListView();
+        ListView<T> targetList = getTargetListView();
+
+        StackPane stackPane = new StackPane();
+        stackPane.setAlignment(Pos.CENTER);
+
+        Orientation orientation = getSkinnable().getOrientation();
+
+        if (orientation == Orientation.HORIZONTAL) {
+            setHorizontalViewContraints();
+            
+            if (sourceHeader != null) {
+                gridPane.add(sourceHeader, 0, 0);
+            }
+
+            if (targetHeader != null) {
+                gridPane.add(targetHeader, 2, 0);
+            }
+
+            if (sourceList != null) {
+                gridPane.add(sourceList, 0, 1);
+            }
+
+            if (targetList != null) {
+                gridPane.add(targetList, 2, 1);
+            }
+
+            if (sourceFooter != null) {
+                gridPane.add(sourceFooter, 0, 2);
+            }
+
+            if (targetFooter != null) {
+                gridPane.add(targetFooter, 2, 2);
+            }
+
+            stackPane.getChildren().add(verticalButtonBox);
+            gridPane.add(stackPane, 1, 1);
+        } else {
+            setVerticalViewContraints();
+            
+            if (sourceHeader != null) {
+                gridPane.add(sourceHeader, 0, 0);
+            }
+
+            if (targetHeader != null) {
+                gridPane.add(targetHeader, 0, 4);
+            }
+
+            if (sourceList != null) {
+                gridPane.add(sourceList, 0, 1);
+            }
+
+            if (targetList != null) {
+                gridPane.add(targetList, 0, 5);
+            }
+
+            if (sourceFooter != null) {
+                gridPane.add(sourceFooter, 0, 2);
+            }
+
+            if (targetFooter != null) {
+                gridPane.add(targetFooter, 0, 6);
+            }
+
+            stackPane.getChildren().add(horizontalButtonBox);
+            gridPane.add(stackPane, 0, 3);
+        }
+    }
+
+    private void moveToTarget() {
+        move(getSourceListView(), getTargetListView());
+        getSourceListView().getSelectionModel().clearSelection();
+    }
+
+    private void moveToTargetAll() {
+        move(getSourceListView(), getTargetListView(), new ArrayList<>(
+                getSourceListView().getItems()));
+        getSourceListView().getSelectionModel().clearSelection();
+    }
+
+    private void moveToSource() {
+        move(getTargetListView(), getSourceListView());
+        getTargetListView().getSelectionModel().clearSelection();
+    }
+
+    private void moveToSourceAll() {
+        move(getTargetListView(), getSourceListView(), new ArrayList<>(
+                getTargetListView().getItems()));
+        getTargetListView().getSelectionModel().clearSelection();
+    }
+
+    private void move(ListView<T> viewA, ListView<T> viewB) {
+        List<T> selectedItems = new ArrayList<>(viewA.getSelectionModel()
+                .getSelectedItems());
+        move(viewA, viewB, selectedItems);
+    }
+
+    private void move(ListView<T> viewA, ListView<T> viewB, List<T> items) {
+        for (T item : items) {
+            viewA.getItems().remove(item);
+            viewB.getItems().add(item);
+        }
+    }
+
+    /**
+     * Returns the source list view (shown on the left-hand side).
+     *
+     * @return the source list view
+     */
+    public final ListView<T> getSourceListView() {
+        return sourceListView;
+    }
+
+    /**
+     * Returns the target list view (shown on the right-hand side).
+     *
+     * @return the target list view
+     */
+    public final ListView<T> getTargetListView() {
+        return targetListView;
+    }
+
+    /**
+     * Creates the {@link ListView} instance used on the left-hand side as the
+     * source list. This method can be overridden to provide a customized list
+     * view control.
+     *
+     * @return the source list view
+     */
+    protected ListView<T> createSourceListView() {
+        return createListView();
+    }
+
+    /**
+     * Creates the {@link ListView} instance used on the right-hand side as the
+     * target list. This method can be overridden to provide a customized list
+     * view control.
+     *
+     * @return the target list view
+     */
+    protected ListView<T> createTargetListView() {
+        return createListView();
+    }
+
+    private ListView<T> createListView() {
+        ListView<T> view = new ListView<>();
+        view.getSelectionModel().setSelectionMode(MULTIPLE);
+        return view;
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/MaskerPaneSkin.java b/src/impl/org/controlsfx/skin/MaskerPaneSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..0e7cf616cf6fabaf8330826cd1e7a9720088ae19
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/MaskerPaneSkin.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import javafx.geometry.Pos;
+import javafx.scene.control.Label;
+import javafx.scene.control.SkinBase;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+import org.controlsfx.control.MaskerPane;
+
+public class MaskerPaneSkin extends SkinBase<MaskerPane> {
+
+    public MaskerPaneSkin(MaskerPane maskerPane) {
+        super(maskerPane);
+        getChildren().add(createMasker(maskerPane));
+    }
+
+    private StackPane createMasker(MaskerPane maskerPane) {
+        VBox vBox = new VBox();
+        vBox.setAlignment(Pos.CENTER);
+        vBox.setSpacing(10.0);
+        vBox.getStyleClass().add("masker-center"); //$NON-NLS-1$
+
+        vBox.getChildren().add(createLabel());
+        vBox.getChildren().add(createProgressIndicator());
+
+        HBox hBox = new HBox();
+        hBox.setAlignment(Pos.CENTER);
+        hBox.getChildren().addAll(vBox);
+
+        StackPane glass = new StackPane();
+        glass.setAlignment(Pos.CENTER);
+        glass.getStyleClass().add("masker-glass"); //$NON-NLS-1$
+        glass.getChildren().add(hBox);
+
+        return glass;
+    }
+
+    private Label createLabel() {
+        Label text = new Label();
+        text.textProperty().bind(getSkinnable().textProperty());
+        text.getStyleClass().add("masker-text"); //$NON-NLS-1$
+        return text;
+    }
+
+    private Label createProgressIndicator() {
+        Label graphic = new Label();
+        graphic.setGraphic(getSkinnable().getProgressNode());
+        graphic.visibleProperty().bind(getSkinnable().progressVisibleProperty());
+        graphic.getStyleClass().add("masker-graphic"); //$NON-NLS-1$
+        return graphic;
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/MasterDetailPaneSkin.java b/src/impl/org/controlsfx/skin/MasterDetailPaneSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a954b89eac3ca713c98b422842994177de4b11a
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/MasterDetailPaneSkin.java
@@ -0,0 +1,473 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import static java.lang.Double.MAX_VALUE;
+import static javafx.geometry.Orientation.HORIZONTAL;
+import static javafx.geometry.Orientation.VERTICAL;
+
+import java.util.List;
+
+import javafx.animation.Animation;
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.Timeline;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ListChangeListener;
+import javafx.geometry.Side;
+import javafx.scene.Node;
+import javafx.scene.control.SkinBase;
+import javafx.scene.control.SplitPane;
+import javafx.scene.control.SplitPane.Divider;
+import javafx.scene.layout.Region;
+import javafx.util.Duration;
+
+import org.controlsfx.control.MasterDetailPane;
+
+public class MasterDetailPaneSkin extends SkinBase<MasterDetailPane> {
+
+    private boolean changing = false;
+    private SplitPane splitPane;
+    private final Timeline timeline = new Timeline();
+    private BooleanProperty showDetailForTimeline = new SimpleBooleanProperty();
+
+    public MasterDetailPaneSkin(MasterDetailPane pane) {
+        super(pane);
+
+        this.splitPane = new SplitPane();
+        this.splitPane.setDividerPosition(0, pane.getDividerPosition());
+
+        /**
+         * We listen to the change of dividers (when adding or removing node), and then
+         * we listen to their position to update correctly the dividerPosition of 
+         * the MasterDetailPane.
+         */
+        this.splitPane.getDividers().addListener(new ListChangeListener<Divider>() {
+
+            @Override
+            public void onChanged(ListChangeListener.Change<? extends Divider> change) {
+                while (change.next()) {
+                    if (change.wasAdded()) {
+                        change.getAddedSubList().get(0).positionProperty().addListener(updateDividerPositionListener);
+                    } else if (change.wasRemoved()) {
+                        change.getRemoved().get(0).positionProperty().removeListener(updateDividerPositionListener);
+                    }
+                }
+            }
+        });
+        
+        SplitPane.setResizableWithParent(getSkinnable().getDetailNode(), false);
+
+        switch (getSkinnable().getDetailSide()) {
+            case BOTTOM:
+            case TOP:
+                splitPane.setOrientation(VERTICAL);
+                break;
+            case LEFT:
+            case RIGHT:
+                splitPane.setOrientation(HORIZONTAL);
+                break;
+        }
+
+        getSkinnable().masterNodeProperty().addListener(
+                new ChangeListener<Node>() {
+                    @Override
+                    public void changed(ObservableValue<? extends Node> value,
+                            Node oldNode, Node newNode) {
+
+                        if (oldNode != null) {
+                            splitPane.getItems().remove(oldNode);
+                        }
+
+                        if (newNode != null) {
+
+                            updateMinAndMaxSizes();
+
+                            int masterIndex = 0;
+                            switch (splitPane.getOrientation()) {
+                                case HORIZONTAL:
+                                    switch (getSkinnable().getDetailSide()) {
+                                        case LEFT:
+                                            masterIndex = 1;
+                                            break;
+                                        case RIGHT:
+                                            masterIndex = 0;
+                                            break;
+                                        default:
+                                            throw new IllegalArgumentException(
+                                                    "illegal details position " //$NON-NLS-1$
+                                                            + getSkinnable()
+                                                            .getDetailSide()
+                                                            + " for orientation " //$NON-NLS-1$
+                                                            + splitPane
+                                                            .getOrientation());
+                                    }
+                                    break;
+                                case VERTICAL:
+                                    switch (getSkinnable().getDetailSide()) {
+                                        case TOP:
+                                            masterIndex = 1;
+                                            break;
+                                        case BOTTOM:
+                                            masterIndex = 0;
+                                            break;
+                                        default:
+                                            throw new IllegalArgumentException(
+                                                    "illegal details position " //$NON-NLS-1$
+                                                            + getSkinnable()
+                                                            .getDetailSide()
+                                                            + " for orientation " //$NON-NLS-1$
+                                                            + splitPane
+                                                            .getOrientation());
+                                    }
+                                    break;
+                            }
+                            List<Node> items = splitPane.getItems();
+                            if (items.isEmpty()) {
+                                items.add(newNode);
+                            } else {
+                                items.add(masterIndex, newNode);
+                            }
+                        }
+                    }
+                });
+
+        getSkinnable().detailNodeProperty().addListener(
+                new ChangeListener<Node>() {
+                    @Override
+                    public void changed(ObservableValue<? extends Node> value,
+                            Node oldNode, Node newNode) {
+
+                        if (oldNode != null) {
+                            splitPane.getItems().remove(oldNode);
+                        }
+
+                        /**
+                        * If the detailNode is not showing, we do not force
+                        * it to show.
+                        */
+                        if (newNode != null && getSkinnable().isShowDetailNode()) {
+
+                            /**
+                             * Force the divider to take the value of the Pane,
+                             * and not compute his.
+                             */
+                            splitPane.setDividerPositions(getSkinnable().getDividerPosition());
+                            updateMinAndMaxSizes();
+
+                            SplitPane.setResizableWithParent(newNode, false);
+
+                            int detailsIndex = 0;
+                            switch (splitPane.getOrientation()) {
+                                case HORIZONTAL:
+                                    switch (getSkinnable().getDetailSide()) {
+                                        case LEFT:
+                                            detailsIndex = 0;
+                                            break;
+                                        case RIGHT:
+                                            detailsIndex = 1;
+                                            break;
+                                        default:
+                                            throw new IllegalArgumentException(
+                                                    "illegal details position " //$NON-NLS-1$
+                                                    + getSkinnable()
+                                                    .getDetailSide()
+                                                    + " for orientation " //$NON-NLS-1$
+                                                    + splitPane
+                                                    .getOrientation());
+                                    }
+                                    break;
+                                case VERTICAL:
+                                    switch (getSkinnable().getDetailSide()) {
+                                        case TOP:
+                                            detailsIndex = 0;
+                                            break;
+                                        case BOTTOM:
+                                            detailsIndex = 1;
+                                            break;
+                                        default:
+                                            throw new IllegalArgumentException(
+                                                    "illegal details position " //$NON-NLS-1$
+                                                    + getSkinnable()
+                                                    .getDetailSide()
+                                                    + " for orientation " //$NON-NLS-1$
+                                                    + splitPane
+                                                    .getOrientation());
+                                    }
+                                    break;
+                            }
+                            List<Node> items = splitPane.getItems();
+                            if (items.isEmpty()) {
+                                items.add(newNode);
+                            } else {
+                                items.add(detailsIndex, newNode);
+                            }
+                        }
+                    }
+                });
+
+        getSkinnable().showDetailNodeProperty().addListener(
+                new ChangeListener<Boolean>() {
+                    @Override
+                    public void changed(
+                            ObservableValue<? extends Boolean> value,
+                            Boolean oldShow, Boolean newShow) {
+                                /**
+                                 * https://bitbucket.org/controlsfx/controlsfx/issue/456/masterdetailpane-bug-of-adding-infinite
+                                 *
+                                 * Fixed bug - when close or show is still animated jump to last frame of animation
+                                 ** and fire finished event to complete the previous demand
+                                 *
+                                 */
+                                if (getSkinnable().isAnimated() && timeline.getStatus() == Animation.Status.RUNNING) {
+                                    timeline.jumpTo("endAnimation");
+                                    timeline.getOnFinished().handle(null);
+                                }
+
+                                if (newShow) {
+                                    open();
+                                } else {
+                                    close();
+                                }
+                            }
+                });
+
+        getSkinnable().detailSideProperty().addListener(
+                new ChangeListener<Side>() {
+                    @Override
+                    public void changed(ObservableValue<? extends Side> value,
+                            Side oldPos, Side newPos) {
+                        if (getSkinnable().isShowDetailNode()) {
+                            splitPane.getItems().clear();
+                        }
+                        switch (newPos) {
+                            case TOP:
+                            case BOTTOM:
+                                splitPane.setOrientation(VERTICAL);
+                                break;
+                            case LEFT:
+                            case RIGHT:
+                                splitPane.setOrientation(HORIZONTAL);
+                        }
+                        switch (newPos) {
+                            case TOP:
+                            case LEFT:
+                                if (getSkinnable().isShowDetailNode()) {
+                                    splitPane.getItems().add(
+                                            getSkinnable().getDetailNode());
+                                    splitPane.getItems().add(
+                                            getSkinnable().getMasterNode());
+                                }
+                                switch (oldPos) {
+                                    case BOTTOM:
+                                    case RIGHT:
+                                        getSkinnable().setDividerPosition(1 - getSkinnable().getDividerPosition());
+                                        break;
+                                    default:
+                                        break;
+                                }
+                                break;
+                            case BOTTOM:
+                            case RIGHT:
+                                if (getSkinnable().isShowDetailNode()) {
+                                    splitPane.getItems().add(
+                                            getSkinnable().getMasterNode());
+                                    splitPane.getItems().add(
+                                            getSkinnable().getDetailNode());
+                                }
+                                switch (oldPos) {
+                                    case TOP:
+                                    case LEFT:
+                                        getSkinnable().setDividerPosition(1 - getSkinnable().getDividerPosition());
+                                        break;
+                                    default:
+                                        break;
+                                }
+                                break;
+                        }
+                        if (getSkinnable().isShowDetailNode()) {
+                            splitPane.setDividerPositions(getSkinnable().getDividerPosition());
+                        }
+                    }
+                });
+
+        updateMinAndMaxSizes();
+
+        getChildren().add(splitPane);
+
+        splitPane.getItems().add(getSkinnable().getMasterNode());
+
+        if (getSkinnable().isShowDetailNode()) {
+            switch (getSkinnable().getDetailSide()) {
+                case TOP:
+                case LEFT:
+                    splitPane.getItems().add(0, getSkinnable().getDetailNode());
+                    break;
+                case BOTTOM:
+                case RIGHT:
+                    splitPane.getItems().add(getSkinnable().getDetailNode());
+                    break;
+            }
+
+            bindDividerPosition();
+        }
+
+        timeline.setOnFinished(evt -> {
+            if (!showDetailForTimeline.get()) {
+                unbindDividerPosition();
+                splitPane.getItems().remove(
+                        getSkinnable().getDetailNode());
+                getSkinnable().getDetailNode().setOpacity(1);
+            }
+            changing = false;
+        });
+    }
+
+    private InvalidationListener listenersDivider = new InvalidationListener() {
+        @Override
+        public void invalidated(Observable arg0) {
+            changing = true;
+            splitPane.setDividerPosition(0, getSkinnable().getDividerPosition());
+            changing = false;
+        }
+    };
+
+    private void bindDividerPosition() {
+        getSkinnable().dividerPositionProperty().addListener(listenersDivider);
+    }
+
+    private void unbindDividerPosition() {
+        getSkinnable().dividerPositionProperty().removeListener(listenersDivider);
+    }
+
+    private void updateMinAndMaxSizes() {
+        if (getSkinnable().getMasterNode() instanceof Region) {
+            ((Region) getSkinnable().getMasterNode()).setMinSize(0, 0);
+            ((Region) getSkinnable().getMasterNode()).setMaxSize(MAX_VALUE,
+                    MAX_VALUE);
+        }
+
+        if (getSkinnable().getDetailNode() instanceof Region) {
+            ((Region) getSkinnable().getDetailNode()).setMinSize(0, 0);
+            ((Region) getSkinnable().getDetailNode()).setMaxSize(MAX_VALUE,
+                    MAX_VALUE);
+        }
+    }
+
+    private void open() {
+        changing = true;
+        Node node = getSkinnable().getDetailNode();
+
+        switch (getSkinnable().getDetailSide()) {
+            case TOP:
+            case LEFT:
+                splitPane.getItems().add(0, node);
+                splitPane.setDividerPositions(0);
+                break;
+            case BOTTOM:
+            case RIGHT:
+                splitPane.getItems().add(node);
+                splitPane.setDividerPositions(1);
+                break;
+        }
+
+        updateMinAndMaxSizes();
+        maybeAnimatePositionChange(getSkinnable().getDividerPosition(), true);
+    }
+
+    private void close() {
+        changing = true;
+        if (!splitPane.getDividers().isEmpty()) {
+
+            /*
+             * Do we collapse by moving the divider to the left/right or
+             * top/bottom?
+             */
+            double targetLocation = 0;
+            switch (getSkinnable().getDetailSide()) {
+                case BOTTOM:
+                case RIGHT:
+                    targetLocation = 1;
+                    break;
+                default:
+                    break;
+            }
+
+            maybeAnimatePositionChange(targetLocation, false);
+        }
+    }
+
+    private void maybeAnimatePositionChange(final double position,
+            final boolean showDetail) {
+        showDetailForTimeline.set(showDetail);
+
+        Divider divider = splitPane.getDividers().get(0);
+
+        if (showDetailForTimeline.get()) {
+            unbindDividerPosition();
+            bindDividerPosition();
+        }
+
+        if (getSkinnable().isAnimated()) {
+            KeyValue positionKeyValue = new KeyValue(
+                    divider.positionProperty(), position);
+            KeyValue opacityKeyValue = new KeyValue(getSkinnable()
+                    .getDetailNode().opacityProperty(), showDetailForTimeline.get() ? 1 : 0);
+
+            KeyFrame keyFrame = new KeyFrame(Duration.seconds(.1), "endAnimation", positionKeyValue, opacityKeyValue);
+
+            timeline.getKeyFrames().clear();
+            timeline.getKeyFrames().add(keyFrame);
+
+            timeline.playFromStart();
+        } else {
+            getSkinnable().getDetailNode().setOpacity(1);
+            divider.setPosition(position);
+
+            if (!showDetailForTimeline.get()) {
+                unbindDividerPosition();
+                splitPane.getItems().remove(getSkinnable().getDetailNode());
+            }
+            changing = false;
+        }
+    }
+
+    private ChangeListener<Number> updateDividerPositionListener = new ChangeListener<Number>() {
+
+        @Override
+        public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
+            if (!changing) {
+                getSkinnable().setDividerPosition(t1.doubleValue());
+            }
+        }
+    };
+}
diff --git a/src/impl/org/controlsfx/skin/NotificationBar.java b/src/impl/org/controlsfx/skin/NotificationBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..2702eba6ef37de72364f3cb3445719a3f9fdede3
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/NotificationBar.java
@@ -0,0 +1,309 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import javafx.animation.Animation.Status;
+import javafx.animation.Interpolator;
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.Timeline;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.geometry.VPos;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonBar;
+import javafx.scene.control.Label;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.StackPane;
+import javafx.util.Duration;
+
+import org.controlsfx.control.NotificationPane;
+import org.controlsfx.control.action.Action;
+import org.controlsfx.control.action.ActionUtils;
+
+@SuppressWarnings("deprecation")
+public abstract class NotificationBar extends Region {
+
+    private static final double MIN_HEIGHT = 40;
+
+    final Label label;
+    Label title;
+    ButtonBar actionsBar;
+    Button closeBtn;
+
+    private final GridPane pane;
+    
+    public DoubleProperty transition = new SimpleDoubleProperty() {
+        @Override protected void invalidated() {
+            requestContainerLayout();
+        }
+    };
+    
+    
+    public void requestContainerLayout() {
+        layoutChildren();
+    }
+    
+    public String getTitle() {
+        return ""; //$NON-NLS-1$
+    }
+    
+    public boolean isCloseButtonVisible() {
+        return true;
+    }
+    
+    public abstract String getText();
+    public abstract Node getGraphic();
+    public abstract ObservableList<Action> getActions();
+    public abstract void hide();
+    public abstract boolean isShowing();
+    public abstract boolean isShowFromTop();
+    
+    public abstract double getContainerHeight();
+    public abstract void relocateInParent(double x, double y);
+    
+    public NotificationBar() {
+        getStyleClass().add("notification-bar"); //$NON-NLS-1$
+        
+        setVisible(isShowing());
+        
+        pane = new GridPane();
+        pane.getStyleClass().add("pane"); //$NON-NLS-1$
+        pane.setAlignment(Pos.BASELINE_LEFT);
+        getChildren().setAll(pane);
+        
+        // initialise title area, if one is set
+        String titleStr = getTitle();
+        if (titleStr != null && ! titleStr.isEmpty()) {
+            title = new Label();
+            title.getStyleClass().add("title"); //$NON-NLS-1$
+            title.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
+            GridPane.setHgrow(title, Priority.ALWAYS);
+
+            title.setText(titleStr);
+            title.opacityProperty().bind(transition);
+        }
+        
+        // initialise label area
+        label = new Label();
+        label.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
+        GridPane.setVgrow(label, Priority.ALWAYS);
+        GridPane.setHgrow(label, Priority.ALWAYS);
+
+        label.setText(getText());
+        label.setGraphic(getGraphic());
+        label.opacityProperty().bind(transition);
+
+        // initialise actions area
+        getActions().addListener(new InvalidationListener() {
+            @Override public void invalidated(Observable arg0) {
+                updatePane();
+            }
+        });
+
+        // initialise close button area
+        closeBtn = new Button();
+        closeBtn.setOnAction(new EventHandler<ActionEvent>() {
+            @Override public void handle(ActionEvent arg0) {
+                hide();
+            }
+        });
+        closeBtn.getStyleClass().setAll("close-button"); //$NON-NLS-1$
+        StackPane graphic = new StackPane();
+        graphic.getStyleClass().setAll("graphic"); //$NON-NLS-1$
+        closeBtn.setGraphic(graphic);
+        closeBtn.setMinSize(17, 17);
+        closeBtn.setPrefSize(17, 17);
+        closeBtn.setFocusTraversable(false);
+        closeBtn.opacityProperty().bind(transition);
+        GridPane.setMargin(closeBtn, new Insets(0, 0, 0, 8));
+        
+        // position the close button in the best place, depending on the height
+        double minHeight = minHeight(-1);
+        GridPane.setValignment(closeBtn, minHeight == MIN_HEIGHT ? VPos.CENTER : VPos.TOP);
+        
+        // put it all together
+        updatePane();
+    }
+
+    void updatePane() {
+        actionsBar = ActionUtils.createButtonBar(getActions());
+        actionsBar.opacityProperty().bind(transition);
+        GridPane.setHgrow(actionsBar, Priority.SOMETIMES);
+        pane.getChildren().clear();
+        
+        int row = 0;
+        
+        if (title != null) {
+            pane.add(title, 0, row++);
+        }
+        
+        pane.add(label, 0, row);
+        pane.add(actionsBar, 1, row);
+        
+        if (isCloseButtonVisible()) {
+            pane.add(closeBtn, 2, 0, 1, row+1);
+        }
+    }
+
+    @Override protected void layoutChildren() {
+        final double w = getWidth();
+        final double h = computePrefHeight(-1);
+        
+        final double notificationBarHeight = prefHeight(w);
+        final double notificationMinHeight = minHeight(w);
+        
+        if (isShowFromTop()) {
+            // place at top of area
+            pane.resize(w, h);
+            relocateInParent(0, (transition.get() - 1) * notificationMinHeight);
+        } else {
+            // place at bottom of area
+            pane.resize(w, notificationBarHeight);
+            relocateInParent(0, getContainerHeight() - notificationBarHeight);
+        }
+    }
+
+    @Override protected double computeMinHeight(double width) {
+        return Math.max(super.computePrefHeight(width), MIN_HEIGHT);
+    }
+
+    @Override protected double computePrefHeight(double width) {
+        return Math.max(pane.prefHeight(width), minHeight(width)) * transition.get();
+    }
+
+    public void doShow() {
+        transitionStartValue = 0;
+        doAnimationTransition();
+    }
+
+    public void doHide() {
+        transitionStartValue = 1;
+        doAnimationTransition();
+    }
+
+
+
+    // --- animation timeline code
+    private final Duration TRANSITION_DURATION = new Duration(350.0);
+    private Timeline timeline;
+    private double transitionStartValue;
+    private void doAnimationTransition() {
+        Duration duration;
+
+        if (timeline != null && (timeline.getStatus() != Status.STOPPED)) {
+            duration = timeline.getCurrentTime();
+
+            // fix for #70 - the notification pane freezes up as it has zero
+            // duration to expand / contract
+            duration = duration == Duration.ZERO ? TRANSITION_DURATION : duration;
+            transitionStartValue = transition.get();
+            // --- end of fix
+
+            timeline.stop();
+        } else {
+            duration = TRANSITION_DURATION;
+        }
+
+        timeline = new Timeline();
+        timeline.setCycleCount(1);
+
+        KeyFrame k1, k2;
+
+        if (isShowing()) {
+            k1 = new KeyFrame(
+                    Duration.ZERO,
+                    new EventHandler<ActionEvent>() {
+                        @Override public void handle(ActionEvent event) {
+                            // start expand
+                            setCache(true);
+                            setVisible(true);
+
+                            pane.fireEvent(new Event(NotificationPane.ON_SHOWING));
+                        }
+                    },
+                    new KeyValue(transition, transitionStartValue)
+                    );
+
+            k2 = new KeyFrame(
+                    duration,
+                    new EventHandler<ActionEvent>() {
+                        @Override public void handle(ActionEvent event) {
+                            // end expand
+                            pane.setCache(false);
+
+                            pane.fireEvent(new Event(NotificationPane.ON_SHOWN));
+                        }
+                    },
+                    new KeyValue(transition, 1, Interpolator.EASE_OUT)
+
+                    );
+        } else {
+            k1 = new KeyFrame(
+                    Duration.ZERO,
+                    new EventHandler<ActionEvent>() {
+                        @Override public void handle(ActionEvent event) {
+                            // Start collapse
+                            pane.setCache(true);
+
+                            pane.fireEvent(new Event(NotificationPane.ON_HIDING));
+                        }
+                    },
+                    new KeyValue(transition, transitionStartValue)
+                    );
+
+            k2 = new KeyFrame(
+                    duration,
+                    new EventHandler<ActionEvent>() {
+                        @Override public void handle(ActionEvent event) {
+                            // end collapse
+                            setCache(false);
+                            setVisible(false);
+
+                            pane.fireEvent(new Event(NotificationPane.ON_HIDDEN));
+                        }
+                    },
+                    new KeyValue(transition, 0, Interpolator.EASE_IN)
+                    );
+        }
+
+        timeline.getKeyFrames().setAll(k1, k2);
+        timeline.play();
+    }
+}
+
diff --git a/src/impl/org/controlsfx/skin/NotificationPaneSkin.java b/src/impl/org/controlsfx/skin/NotificationPaneSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..58d404608ff3580eb0a3c1d37e65dc91bfcdf042
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/NotificationPaneSkin.java
@@ -0,0 +1,201 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import java.util.Collections;
+
+import com.sun.javafx.scene.traversal.ParentTraversalEngine;
+import javafx.collections.ObservableList;
+import javafx.scene.Node;
+import javafx.scene.shape.Rectangle;
+
+import org.controlsfx.control.NotificationPane;
+import org.controlsfx.control.action.Action;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+
+public class NotificationPaneSkin extends BehaviorSkinBase<NotificationPane, BehaviorBase<NotificationPane>> {
+
+    private NotificationBar notificationBar;
+    private Node content;
+    private Rectangle clip = new Rectangle();
+
+    public NotificationPaneSkin(final NotificationPane control) {
+        super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
+
+        notificationBar = new NotificationBar() {
+            @Override public void requestContainerLayout() {
+                control.requestLayout();
+            }
+
+            @Override public String getText() {
+                return control.getText();
+            }
+
+            @Override public Node getGraphic() {
+                return control.getGraphic();
+            }
+
+            @Override public ObservableList<Action> getActions() {
+                return control.getActions();
+            }
+
+            @Override public boolean isShowing() {
+                return control.isShowing();
+            }
+
+            @Override public boolean isShowFromTop() {
+                return control.isShowFromTop();
+            }
+
+            @Override public void hide() {
+                control.hide();
+            }
+
+            @Override public boolean isCloseButtonVisible() {
+                    return control.isCloseButtonVisible();
+            }
+
+            @Override public double getContainerHeight() {
+                return control.getHeight();
+            }
+
+            @Override public void relocateInParent(double x, double y) {
+                notificationBar.relocate(x, y);
+            }
+        };
+
+        control.setClip(clip);
+        updateContent();
+
+        registerChangeListener(control.heightProperty(), "HEIGHT"); //$NON-NLS-1$
+        registerChangeListener(control.contentProperty(), "CONTENT"); //$NON-NLS-1$
+        registerChangeListener(control.textProperty(), "TEXT"); //$NON-NLS-1$
+        registerChangeListener(control.graphicProperty(), "GRAPHIC"); //$NON-NLS-1$
+        registerChangeListener(control.showingProperty(), "SHOWING"); //$NON-NLS-1$
+        registerChangeListener(control.showFromTopProperty(), "SHOW_FROM_TOP"); //$NON-NLS-1$
+        registerChangeListener(control.closeButtonVisibleProperty(), "CLOSE_BUTTON_VISIBLE"); //$NON-NLS-1$
+
+        // Fix for Issue #522: Prevent NotificationPane from receiving focus
+        ParentTraversalEngine engine = new ParentTraversalEngine(getSkinnable());
+        getSkinnable().setImpl_traversalEngine(engine);
+        engine.setOverriddenFocusTraversability(false);
+    }
+    
+    @Override protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+        
+        if ("CONTENT".equals(p)) { //$NON-NLS-1$
+            updateContent();
+        } else if ("TEXT".equals(p)) { //$NON-NLS-1$
+            notificationBar.label.setText(getSkinnable().getText());
+        } else if ("GRAPHIC".equals(p)) { //$NON-NLS-1$
+            notificationBar.label.setGraphic(getSkinnable().getGraphic());
+        } else if ("SHOWING".equals(p)) { //$NON-NLS-1$
+            if (getSkinnable().isShowing()) {
+                notificationBar.doShow();
+            } else {
+                notificationBar.doHide();
+            }
+        } else if ("SHOW_FROM_TOP".equals(p)) { //$NON-NLS-1$
+            if (getSkinnable().isShowing()) {
+                getSkinnable().requestLayout();
+            }
+        } else if ("CLOSE_BUTTON_VISIBLE".equals(p)) { //$NON-NLS-1$
+            notificationBar.updatePane();
+        }else if ( "HEIGHT".equals(p)){
+            // For resolving https://bitbucket.org/controlsfx/controlsfx/issue/409
+            if (getSkinnable().isShowing() && !getSkinnable().isShowFromTop()) {
+                notificationBar.requestLayout();
+            }
+        }
+    }
+    
+    private void updateContent() {
+        if (content != null) {
+            getChildren().remove(content);
+        }
+        
+        content = getSkinnable().getContent();
+        
+        if (content == null) {
+            getChildren().setAll(notificationBar);
+        } else {
+            getChildren().setAll(content, notificationBar);
+        }
+    }
+    
+    @Override protected void layoutChildren(double x, double y, double w, double h) {
+        final double notificationBarHeight = notificationBar.prefHeight(w);
+        
+        notificationBar.resize(w, notificationBarHeight);
+        
+        // layout the content
+        if (content != null) {
+            content.resizeRelocate(x, y, w, h);
+        }
+        
+        // and update the clip so that the notification bar does not draw outside
+        // the bounds of the notification pane
+        clip.setX(x);
+        clip.setY(y);
+        clip.setWidth(w);
+        clip.setHeight(h);
+    }
+    
+    @Override
+    protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return content == null ? 0 : content.minWidth(height);
+    };
+    
+    @Override
+    protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return content == null ? 0 : content.minHeight(width);
+    };
+    
+    @Override
+    protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return content == null ? 0 : content.prefWidth(height);
+    };
+    
+    @Override
+    protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return content == null ? 0 : content.prefHeight(width);
+    };
+    
+    @Override
+    protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return content == null ? 0 : content.maxWidth(height);
+    };
+    
+    @Override
+    protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return content == null ? 0 : content.maxHeight(width);
+    };
+}
diff --git a/src/impl/org/controlsfx/skin/PlusMinusSliderSkin.java b/src/impl/org/controlsfx/skin/PlusMinusSliderSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..f5bf821efabf800b7f275f4abe2430ff7e00b516
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/PlusMinusSliderSkin.java
@@ -0,0 +1,160 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import static javafx.scene.input.MouseEvent.MOUSE_PRESSED;
+import static javafx.scene.input.MouseEvent.MOUSE_RELEASED;
+import javafx.animation.AnimationTimer;
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.Timeline;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.EventHandler;
+import javafx.geometry.Orientation;
+import javafx.scene.control.SkinBase;
+import javafx.scene.control.Slider;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.Region;
+import javafx.util.Duration;
+
+import org.controlsfx.control.PlusMinusSlider;
+import org.controlsfx.control.PlusMinusSlider.PlusMinusEvent;
+
+public class PlusMinusSliderSkin extends SkinBase<PlusMinusSlider> {
+    
+	private SliderReader reader;
+
+	private Slider slider;
+
+	private Region plusRegion;
+
+	private Region minusRegion;
+
+	private BorderPane borderPane;
+
+	public PlusMinusSliderSkin(PlusMinusSlider adjuster) {
+		super(adjuster);
+
+		/*
+		 * We are not supporting any key events, yet. Adding this filter makes
+		 * sure the user doesn't use the standard key bindings of the slider. In
+		 * that case the thumb would not move itself back automatically (e.g.
+		 * after pressing "arrow right").
+		 */
+		adjuster.addEventFilter(KeyEvent.ANY, new EventHandler<KeyEvent>() {
+			@Override
+			public void handle(KeyEvent event) {
+				event.consume();
+			}
+		});
+
+		slider = new Slider(-1, 1, 0);
+
+		slider.valueProperty().addListener(new ChangeListener<Number>() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable,
+					Number oldValue, Number newValue) {
+				getSkinnable().getProperties().put("plusminusslidervalue", //$NON-NLS-1$
+						newValue.doubleValue());
+			}
+		});
+
+		slider.orientationProperty().bind(adjuster.orientationProperty());
+
+		slider.addEventHandler(MOUSE_PRESSED, new EventHandler<MouseEvent>() {
+
+			@Override
+			public void handle(MouseEvent evt) {
+				reader = new SliderReader();
+				reader.start();
+			}
+		});
+
+		slider.addEventHandler(MOUSE_RELEASED, new EventHandler<MouseEvent>() {
+
+			@Override
+			public void handle(MouseEvent evt) {
+				if (reader != null) {
+					reader.stop();
+				}
+
+				KeyValue keyValue = new KeyValue(slider.valueProperty(), 0);
+				KeyFrame keyFrame = new KeyFrame(Duration.millis(100), keyValue);
+				Timeline timeline = new Timeline(keyFrame);
+				timeline.play();
+			}
+		});
+
+		plusRegion = new Region();
+		plusRegion.getStyleClass().add("adjust-plus"); //$NON-NLS-1$
+
+		minusRegion = new Region();
+		minusRegion.getStyleClass().add("adjust-minus"); //$NON-NLS-1$
+
+		borderPane = new BorderPane();
+
+		updateLayout(adjuster.getOrientation());
+
+		getChildren().add(borderPane);
+
+		adjuster.orientationProperty().addListener((observable, oldValue, newValue) -> updateLayout(newValue));
+	}
+
+	private void updateLayout(Orientation orientation) {
+		borderPane.getChildren().clear();
+
+		switch (orientation) {
+		case HORIZONTAL:
+			borderPane.setLeft(minusRegion);
+			borderPane.setCenter(slider);
+			borderPane.setRight(plusRegion);
+			break;
+		case VERTICAL:
+			borderPane.setTop(plusRegion);
+			borderPane.setCenter(slider);
+			borderPane.setBottom(minusRegion);
+			break;
+		}
+	}
+
+	class SliderReader extends AnimationTimer {
+		private long lastTime = System.currentTimeMillis();
+
+		@Override
+		public void handle(long now) {
+			// max speed: 100 hundred times per second
+			if (now - lastTime > 10000000) {
+				lastTime = now;
+				slider.fireEvent(new PlusMinusEvent(slider, slider,
+						PlusMinusEvent.VALUE_CHANGED, slider.getValue()));
+			}
+		}
+	}
+}
diff --git a/src/impl/org/controlsfx/skin/PopOverSkin.java b/src/impl/org/controlsfx/skin/PopOverSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d18a86c6002cf852990c6996b17a829391efea2
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/PopOverSkin.java
@@ -0,0 +1,717 @@
+/**
+ * Copyright (c) 2013 - 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import static java.lang.Double.MAX_VALUE;
+import static javafx.geometry.Pos.CENTER_LEFT;
+import static javafx.scene.control.ContentDisplay.GRAPHIC_ONLY;
+import static javafx.scene.paint.Color.YELLOW;
+import static org.controlsfx.control.PopOver.ArrowLocation.BOTTOM_CENTER;
+import static org.controlsfx.control.PopOver.ArrowLocation.BOTTOM_LEFT;
+import static org.controlsfx.control.PopOver.ArrowLocation.BOTTOM_RIGHT;
+import static org.controlsfx.control.PopOver.ArrowLocation.LEFT_BOTTOM;
+import static org.controlsfx.control.PopOver.ArrowLocation.LEFT_CENTER;
+import static org.controlsfx.control.PopOver.ArrowLocation.LEFT_TOP;
+import static org.controlsfx.control.PopOver.ArrowLocation.RIGHT_BOTTOM;
+import static org.controlsfx.control.PopOver.ArrowLocation.RIGHT_CENTER;
+import static org.controlsfx.control.PopOver.ArrowLocation.RIGHT_TOP;
+import static org.controlsfx.control.PopOver.ArrowLocation.TOP_CENTER;
+import static org.controlsfx.control.PopOver.ArrowLocation.TOP_LEFT;
+import static org.controlsfx.control.PopOver.ArrowLocation.TOP_RIGHT;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.controlsfx.control.PopOver;
+import org.controlsfx.control.PopOver.ArrowLocation;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.binding.Bindings;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.event.EventHandler;
+import javafx.geometry.Point2D;
+import javafx.geometry.Pos;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.control.Skin;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.StackPane;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.HLineTo;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.PathElement;
+import javafx.scene.shape.QuadCurveTo;
+import javafx.scene.shape.VLineTo;
+import javafx.stage.Window;
+
+public class PopOverSkin implements Skin<PopOver> {
+
+    private static final String DETACHED_STYLE_CLASS = "detached"; //$NON-NLS-1$
+
+    private double xOffset;
+    private double yOffset;
+
+    private boolean tornOff;
+
+    private Label title;
+    private Label closeIcon;
+
+    private Path path;
+    private Path clip;
+
+    private BorderPane content;
+    private StackPane titlePane;
+    private StackPane stackPane;
+
+    private Point2D dragStartLocation;
+
+    private PopOver popOver;
+
+    public PopOverSkin(final PopOver popOver) {
+
+        this.popOver = popOver;
+
+        stackPane = popOver.getRoot();
+        stackPane.setPickOnBounds(false);
+
+        Bindings.bindContent(stackPane.getStyleClass(), popOver.getStyleClass());
+
+        /*
+         * The min width and height equal 2 * corner radius + 2 * arrow indent +
+         * 2 * arrow size.
+         */
+        stackPane.minWidthProperty().bind(
+                Bindings.add(Bindings.multiply(2, popOver.arrowSizeProperty()),
+                        Bindings.add(
+                                Bindings.multiply(2,
+                                        popOver.cornerRadiusProperty()),
+                                Bindings.multiply(2,
+                                        popOver.arrowIndentProperty()))));
+
+        stackPane.minHeightProperty().bind(stackPane.minWidthProperty());
+
+        title = new Label();
+        title.textProperty().bind(popOver.titleProperty());
+        title.setMaxSize(MAX_VALUE, MAX_VALUE);
+        title.setAlignment(Pos.CENTER);
+        title.getStyleClass().add("text"); //$NON-NLS-1$
+
+        closeIcon = new Label();
+        closeIcon.setGraphic(createCloseIcon());
+        closeIcon.setMaxSize(MAX_VALUE, MAX_VALUE);
+        closeIcon.setContentDisplay(GRAPHIC_ONLY);
+        closeIcon.visibleProperty().bind(popOver.detachedProperty().or(popOver.headerAlwaysVisibleProperty()));
+        closeIcon.getStyleClass().add("icon"); //$NON-NLS-1$
+        closeIcon.setAlignment(CENTER_LEFT);
+        closeIcon.getGraphic().setOnMouseClicked(evt -> popOver.hide());
+
+        titlePane = new StackPane();
+        titlePane.getChildren().add(title);
+        titlePane.getChildren().add(closeIcon);
+        titlePane.getStyleClass().add("title"); //$NON-NLS-1$
+
+        content = new BorderPane();
+        content.setCenter(popOver.getContentNode());
+        content.getStyleClass().add("content"); //$NON-NLS-1$
+
+        if (popOver.isDetached() || popOver.isHeaderAlwaysVisible()) {
+            content.setTop(titlePane);
+        }
+
+        if (popOver.isDetached()) {
+            popOver.getStyleClass().add(DETACHED_STYLE_CLASS);
+            content.getStyleClass().add(DETACHED_STYLE_CLASS);
+        }
+
+        popOver.headerAlwaysVisibleProperty().addListener((o, oV, isVisible) -> {
+            if (isVisible) {
+                content.setTop(titlePane);
+            } else if (!popOver.isDetached()) {
+                content.setTop(null);
+            }
+        });
+
+        InvalidationListener updatePathListener = observable -> updatePath();
+        getPopupWindow().xProperty().addListener(updatePathListener);
+        getPopupWindow().yProperty().addListener(updatePathListener);
+        popOver.arrowLocationProperty().addListener(updatePathListener);
+        popOver.contentNodeProperty().addListener(
+                (value, oldContent, newContent) -> content
+                        .setCenter(newContent));
+        popOver.detachedProperty()
+                .addListener((value, oldDetached, newDetached) -> {
+
+                    if (newDetached) {
+                        popOver.getStyleClass().add(DETACHED_STYLE_CLASS);
+                        content.getStyleClass().add(DETACHED_STYLE_CLASS);
+                        content.setTop(titlePane);
+
+                        switch (getSkinnable().getArrowLocation()) {
+                        case LEFT_TOP:
+                        case LEFT_CENTER:
+                        case LEFT_BOTTOM:
+                            popOver.setAnchorX(
+                                    popOver.getAnchorX() + popOver.getArrowSize());
+                            break;
+                        case TOP_LEFT:
+                        case TOP_CENTER:
+                        case TOP_RIGHT:
+                            popOver.setAnchorY(
+                                    popOver.getAnchorY() + popOver.getArrowSize());
+                            break;
+                        default:
+                            break;
+                        }
+                    } else {
+                        popOver.getStyleClass().remove(DETACHED_STYLE_CLASS);
+                        content.getStyleClass().remove(DETACHED_STYLE_CLASS);
+
+                        if (!popOver.isHeaderAlwaysVisible()) {
+                            content.setTop(null);
+                        }
+                    }
+
+                    popOver.sizeToScene();
+
+                    updatePath();
+                });
+
+        path = new Path();
+        path.getStyleClass().add("border"); //$NON-NLS-1$
+        path.setManaged(false);
+
+        clip = new Path();
+
+        /*
+         * The clip is a path and the path has to be filled with a color.
+         * Otherwise clipping will not work.
+         */
+        clip.setFill(YELLOW);
+
+        createPathElements();
+        updatePath();
+
+        final EventHandler<MouseEvent> mousePressedHandler = evt -> {
+            if (popOver.isDetachable() || popOver.isDetached()) {
+                tornOff = false;
+
+                xOffset = evt.getScreenX();
+                yOffset = evt.getScreenY();
+
+                dragStartLocation = new Point2D(xOffset, yOffset);
+            }
+        };
+
+        final EventHandler<MouseEvent> mouseReleasedHandler = evt -> {
+            if (tornOff && !getSkinnable().isDetached()) {
+                tornOff = false;
+                getSkinnable().detach();
+            }
+        };
+
+        final EventHandler<MouseEvent> mouseDragHandler = evt -> {
+            if (popOver.isDetachable() || popOver.isDetached()) {
+                double deltaX = evt.getScreenX() - xOffset;
+                double deltaY = evt.getScreenY() - yOffset;
+
+                Window window = getSkinnable().getScene().getWindow();
+
+                window.setX(window.getX() + deltaX);
+                window.setY(window.getY() + deltaY);
+
+                xOffset = evt.getScreenX();
+                yOffset = evt.getScreenY();
+
+                if (dragStartLocation.distance(xOffset, yOffset) > 20) {
+                    tornOff = true;
+                    updatePath();
+                } else if (tornOff) {
+                    tornOff = false;
+                    updatePath();
+                }
+            }
+        };
+
+        stackPane.setOnMousePressed(mousePressedHandler);
+        stackPane.setOnMouseDragged(mouseDragHandler);
+        stackPane.setOnMouseReleased(mouseReleasedHandler);
+
+        stackPane.getChildren().add(path);
+        stackPane.getChildren().add(content);
+
+        content.setClip(clip);
+    }
+
+    @Override
+    public Node getNode() {
+        return stackPane;
+    }
+
+    @Override
+    public PopOver getSkinnable() {
+        return popOver;
+    }
+
+    @Override
+    public void dispose() {
+    }
+
+    private Node createCloseIcon() {
+        Group group = new Group();
+        group.getStyleClass().add("graphics"); //$NON-NLS-1$
+
+        Circle circle = new Circle();
+        circle.getStyleClass().add("circle"); //$NON-NLS-1$
+        circle.setRadius(6);
+        circle.setCenterX(6);
+        circle.setCenterY(6);
+        group.getChildren().add(circle);
+
+        Line line1 = new Line();
+        line1.getStyleClass().add("line"); //$NON-NLS-1$
+        line1.setStartX(4);
+        line1.setStartY(4);
+        line1.setEndX(8);
+        line1.setEndY(8);
+        group.getChildren().add(line1);
+
+        Line line2 = new Line();
+        line2.getStyleClass().add("line"); //$NON-NLS-1$
+        line2.setStartX(8);
+        line2.setStartY(4);
+        line2.setEndX(4);
+        line2.setEndY(8);
+        group.getChildren().add(line2);
+
+        return group;
+    }
+
+    private MoveTo moveTo;
+
+    private QuadCurveTo topCurveTo, rightCurveTo, bottomCurveTo, leftCurveTo;
+
+    private HLineTo lineBTop, lineETop, lineHTop, lineKTop;
+    private LineTo lineCTop, lineDTop, lineFTop, lineGTop, lineITop, lineJTop;
+
+    private VLineTo lineBRight, lineERight, lineHRight, lineKRight;
+    private LineTo lineCRight, lineDRight, lineFRight, lineGRight, lineIRight,
+            lineJRight;
+
+    private HLineTo lineBBottom, lineEBottom, lineHBottom, lineKBottom;
+    private LineTo lineCBottom, lineDBottom, lineFBottom, lineGBottom,
+            lineIBottom, lineJBottom;
+
+    private VLineTo lineBLeft, lineELeft, lineHLeft, lineKLeft;
+    private LineTo lineCLeft, lineDLeft, lineFLeft, lineGLeft, lineILeft,
+            lineJLeft;
+
+    private void createPathElements() {
+        DoubleProperty centerYProperty = new SimpleDoubleProperty();
+        DoubleProperty centerXProperty = new SimpleDoubleProperty();
+
+        DoubleProperty leftEdgeProperty = new SimpleDoubleProperty();
+        DoubleProperty leftEdgePlusRadiusProperty = new SimpleDoubleProperty();
+
+        DoubleProperty topEdgeProperty = new SimpleDoubleProperty();
+        DoubleProperty topEdgePlusRadiusProperty = new SimpleDoubleProperty();
+
+        DoubleProperty rightEdgeProperty = new SimpleDoubleProperty();
+        DoubleProperty rightEdgeMinusRadiusProperty = new SimpleDoubleProperty();
+
+        DoubleProperty bottomEdgeProperty = new SimpleDoubleProperty();
+        DoubleProperty bottomEdgeMinusRadiusProperty = new SimpleDoubleProperty();
+
+        DoubleProperty cornerProperty = getSkinnable().cornerRadiusProperty();
+
+        DoubleProperty arrowSizeProperty = getSkinnable().arrowSizeProperty();
+        DoubleProperty arrowIndentProperty = getSkinnable()
+                .arrowIndentProperty();
+
+        centerYProperty.bind(Bindings.divide(stackPane.heightProperty(), 2));
+        centerXProperty.bind(Bindings.divide(stackPane.widthProperty(), 2));
+
+        leftEdgePlusRadiusProperty.bind(Bindings.add(leftEdgeProperty,
+                getSkinnable().cornerRadiusProperty()));
+
+        topEdgePlusRadiusProperty.bind(Bindings.add(topEdgeProperty,
+                getSkinnable().cornerRadiusProperty()));
+
+        rightEdgeProperty.bind(stackPane.widthProperty());
+        rightEdgeMinusRadiusProperty.bind(Bindings.subtract(rightEdgeProperty,
+                getSkinnable().cornerRadiusProperty()));
+
+        bottomEdgeProperty.bind(stackPane.heightProperty());
+        bottomEdgeMinusRadiusProperty.bind(Bindings.subtract(
+                bottomEdgeProperty, getSkinnable().cornerRadiusProperty()));
+
+        // INIT
+        moveTo = new MoveTo();
+        moveTo.xProperty().bind(leftEdgePlusRadiusProperty);
+        moveTo.yProperty().bind(topEdgeProperty);
+
+        //
+        // TOP EDGE
+        //
+        lineBTop = new HLineTo();
+        lineBTop.xProperty().bind(
+                Bindings.add(leftEdgePlusRadiusProperty, arrowIndentProperty));
+
+        lineCTop = new LineTo();
+        lineCTop.xProperty().bind(
+                Bindings.add(lineBTop.xProperty(), arrowSizeProperty));
+        lineCTop.yProperty().bind(
+                Bindings.subtract(topEdgeProperty, arrowSizeProperty));
+
+        lineDTop = new LineTo();
+        lineDTop.xProperty().bind(
+                Bindings.add(lineCTop.xProperty(), arrowSizeProperty));
+        lineDTop.yProperty().bind(topEdgeProperty);
+
+        lineETop = new HLineTo();
+        lineETop.xProperty().bind(
+                Bindings.subtract(centerXProperty, arrowSizeProperty));
+
+        lineFTop = new LineTo();
+        lineFTop.xProperty().bind(centerXProperty);
+        lineFTop.yProperty().bind(
+                Bindings.subtract(topEdgeProperty, arrowSizeProperty));
+
+        lineGTop = new LineTo();
+        lineGTop.xProperty().bind(
+                Bindings.add(centerXProperty, arrowSizeProperty));
+        lineGTop.yProperty().bind(topEdgeProperty);
+
+        lineHTop = new HLineTo();
+        lineHTop.xProperty().bind(
+                Bindings.subtract(Bindings.subtract(
+                        rightEdgeMinusRadiusProperty, arrowIndentProperty),
+                        Bindings.multiply(arrowSizeProperty, 2)));
+
+        lineITop = new LineTo();
+        lineITop.xProperty().bind(
+                Bindings.subtract(Bindings.subtract(
+                        rightEdgeMinusRadiusProperty, arrowIndentProperty),
+                        arrowSizeProperty));
+        lineITop.yProperty().bind(
+                Bindings.subtract(topEdgeProperty, arrowSizeProperty));
+
+        lineJTop = new LineTo();
+        lineJTop.xProperty().bind(
+                Bindings.subtract(rightEdgeMinusRadiusProperty,
+                        arrowIndentProperty));
+        lineJTop.yProperty().bind(topEdgeProperty);
+
+        lineKTop = new HLineTo();
+        lineKTop.xProperty().bind(rightEdgeMinusRadiusProperty);
+
+        //
+        // RIGHT EDGE
+        //
+        rightCurveTo = new QuadCurveTo();
+        rightCurveTo.xProperty().bind(rightEdgeProperty);
+        rightCurveTo.yProperty().bind(
+                Bindings.add(topEdgeProperty, cornerProperty));
+        rightCurveTo.controlXProperty().bind(rightEdgeProperty);
+        rightCurveTo.controlYProperty().bind(topEdgeProperty);
+
+        lineBRight = new VLineTo();
+        lineBRight.yProperty().bind(
+                Bindings.add(topEdgePlusRadiusProperty, arrowIndentProperty));
+
+        lineCRight = new LineTo();
+        lineCRight.xProperty().bind(
+                Bindings.add(rightEdgeProperty, arrowSizeProperty));
+        lineCRight.yProperty().bind(
+                Bindings.add(lineBRight.yProperty(), arrowSizeProperty));
+
+        lineDRight = new LineTo();
+        lineDRight.xProperty().bind(rightEdgeProperty);
+        lineDRight.yProperty().bind(
+                Bindings.add(lineCRight.yProperty(), arrowSizeProperty));
+
+        lineERight = new VLineTo();
+        lineERight.yProperty().bind(
+                Bindings.subtract(centerYProperty, arrowSizeProperty));
+
+        lineFRight = new LineTo();
+        lineFRight.xProperty().bind(
+                Bindings.add(rightEdgeProperty, arrowSizeProperty));
+        lineFRight.yProperty().bind(centerYProperty);
+
+        lineGRight = new LineTo();
+        lineGRight.xProperty().bind(rightEdgeProperty);
+        lineGRight.yProperty().bind(
+                Bindings.add(centerYProperty, arrowSizeProperty));
+
+        lineHRight = new VLineTo();
+        lineHRight.yProperty().bind(
+                Bindings.subtract(Bindings.subtract(
+                        bottomEdgeMinusRadiusProperty, arrowIndentProperty),
+                        Bindings.multiply(arrowSizeProperty, 2)));
+
+        lineIRight = new LineTo();
+        lineIRight.xProperty().bind(
+                Bindings.add(rightEdgeProperty, arrowSizeProperty));
+        lineIRight.yProperty().bind(
+                Bindings.subtract(Bindings.subtract(
+                        bottomEdgeMinusRadiusProperty, arrowIndentProperty),
+                        arrowSizeProperty));
+
+        lineJRight = new LineTo();
+        lineJRight.xProperty().bind(rightEdgeProperty);
+        lineJRight.yProperty().bind(
+                Bindings.subtract(bottomEdgeMinusRadiusProperty,
+                        arrowIndentProperty));
+
+        lineKRight = new VLineTo();
+        lineKRight.yProperty().bind(bottomEdgeMinusRadiusProperty);
+
+        //
+        // BOTTOM EDGE
+        //
+
+        bottomCurveTo = new QuadCurveTo();
+        bottomCurveTo.xProperty().bind(rightEdgeMinusRadiusProperty);
+        bottomCurveTo.yProperty().bind(bottomEdgeProperty);
+        bottomCurveTo.controlXProperty().bind(rightEdgeProperty);
+        bottomCurveTo.controlYProperty().bind(bottomEdgeProperty);
+
+        lineBBottom = new HLineTo();
+        lineBBottom.xProperty().bind(
+                Bindings.subtract(rightEdgeMinusRadiusProperty,
+                        arrowIndentProperty));
+
+        lineCBottom = new LineTo();
+        lineCBottom.xProperty().bind(
+                Bindings.subtract(lineBBottom.xProperty(), arrowSizeProperty));
+        lineCBottom.yProperty().bind(
+                Bindings.add(bottomEdgeProperty, arrowSizeProperty));
+
+        lineDBottom = new LineTo();
+        lineDBottom.xProperty().bind(
+                Bindings.subtract(lineCBottom.xProperty(), arrowSizeProperty));
+        lineDBottom.yProperty().bind(bottomEdgeProperty);
+
+        lineEBottom = new HLineTo();
+        lineEBottom.xProperty().bind(
+                Bindings.add(centerXProperty, arrowSizeProperty));
+
+        lineFBottom = new LineTo();
+        lineFBottom.xProperty().bind(centerXProperty);
+        lineFBottom.yProperty().bind(
+                Bindings.add(bottomEdgeProperty, arrowSizeProperty));
+
+        lineGBottom = new LineTo();
+        lineGBottom.xProperty().bind(
+                Bindings.subtract(centerXProperty, arrowSizeProperty));
+        lineGBottom.yProperty().bind(bottomEdgeProperty);
+
+        lineHBottom = new HLineTo();
+        lineHBottom.xProperty().bind(
+                Bindings.add(Bindings.add(leftEdgePlusRadiusProperty,
+                        arrowIndentProperty), Bindings.multiply(
+                        arrowSizeProperty, 2)));
+
+        lineIBottom = new LineTo();
+        lineIBottom.xProperty().bind(
+                Bindings.add(Bindings.add(leftEdgePlusRadiusProperty,
+                        arrowIndentProperty), arrowSizeProperty));
+        lineIBottom.yProperty().bind(
+                Bindings.add(bottomEdgeProperty, arrowSizeProperty));
+
+        lineJBottom = new LineTo();
+        lineJBottom.xProperty().bind(
+                Bindings.add(leftEdgePlusRadiusProperty, arrowIndentProperty));
+        lineJBottom.yProperty().bind(bottomEdgeProperty);
+
+        lineKBottom = new HLineTo();
+        lineKBottom.xProperty().bind(leftEdgePlusRadiusProperty);
+
+        //
+        // LEFT EDGE
+        //
+        leftCurveTo = new QuadCurveTo();
+        leftCurveTo.xProperty().bind(leftEdgeProperty);
+        leftCurveTo.yProperty().bind(
+                Bindings.subtract(bottomEdgeProperty, cornerProperty));
+        leftCurveTo.controlXProperty().bind(leftEdgeProperty);
+        leftCurveTo.controlYProperty().bind(bottomEdgeProperty);
+
+        lineBLeft = new VLineTo();
+        lineBLeft.yProperty().bind(
+                Bindings.subtract(bottomEdgeMinusRadiusProperty,
+                        arrowIndentProperty));
+
+        lineCLeft = new LineTo();
+        lineCLeft.xProperty().bind(
+                Bindings.subtract(leftEdgeProperty, arrowSizeProperty));
+        lineCLeft.yProperty().bind(
+                Bindings.subtract(lineBLeft.yProperty(), arrowSizeProperty));
+
+        lineDLeft = new LineTo();
+        lineDLeft.xProperty().bind(leftEdgeProperty);
+        lineDLeft.yProperty().bind(
+                Bindings.subtract(lineCLeft.yProperty(), arrowSizeProperty));
+
+        lineELeft = new VLineTo();
+        lineELeft.yProperty().bind(
+                Bindings.add(centerYProperty, arrowSizeProperty));
+
+        lineFLeft = new LineTo();
+        lineFLeft.xProperty().bind(
+                Bindings.subtract(leftEdgeProperty, arrowSizeProperty));
+        lineFLeft.yProperty().bind(centerYProperty);
+
+        lineGLeft = new LineTo();
+        lineGLeft.xProperty().bind(leftEdgeProperty);
+        lineGLeft.yProperty().bind(
+                Bindings.subtract(centerYProperty, arrowSizeProperty));
+
+        lineHLeft = new VLineTo();
+        lineHLeft.yProperty().bind(
+                Bindings.add(Bindings.add(topEdgePlusRadiusProperty,
+                        arrowIndentProperty), Bindings.multiply(
+                        arrowSizeProperty, 2)));
+
+        lineILeft = new LineTo();
+        lineILeft.xProperty().bind(
+                Bindings.subtract(leftEdgeProperty, arrowSizeProperty));
+        lineILeft.yProperty().bind(
+                Bindings.add(Bindings.add(topEdgePlusRadiusProperty,
+                        arrowIndentProperty), arrowSizeProperty));
+
+        lineJLeft = new LineTo();
+        lineJLeft.xProperty().bind(leftEdgeProperty);
+        lineJLeft.yProperty().bind(
+                Bindings.add(topEdgePlusRadiusProperty, arrowIndentProperty));
+
+        lineKLeft = new VLineTo();
+        lineKLeft.yProperty().bind(topEdgePlusRadiusProperty);
+
+        topCurveTo = new QuadCurveTo();
+        topCurveTo.xProperty().bind(leftEdgePlusRadiusProperty);
+        topCurveTo.yProperty().bind(topEdgeProperty);
+        topCurveTo.controlXProperty().bind(leftEdgeProperty);
+        topCurveTo.controlYProperty().bind(topEdgeProperty);
+    }
+
+    private Window getPopupWindow() {
+        return getSkinnable().getScene().getWindow();
+    }
+
+    private boolean showArrow(ArrowLocation location) {
+        ArrowLocation arrowLocation = getSkinnable().getArrowLocation();
+        return location.equals(arrowLocation) && !getSkinnable().isDetached()
+                && !tornOff;
+    }
+
+    private void updatePath() {
+        List<PathElement> elements = new ArrayList<>();
+        elements.add(moveTo);
+
+        if (showArrow(TOP_LEFT)) {
+            elements.add(lineBTop);
+            elements.add(lineCTop);
+            elements.add(lineDTop);
+        }
+        if (showArrow(TOP_CENTER)) {
+            elements.add(lineETop);
+            elements.add(lineFTop);
+            elements.add(lineGTop);
+        }
+        if (showArrow(TOP_RIGHT)) {
+            elements.add(lineHTop);
+            elements.add(lineITop);
+            elements.add(lineJTop);
+        }
+        elements.add(lineKTop);
+        elements.add(rightCurveTo);
+
+        if (showArrow(RIGHT_TOP)) {
+            elements.add(lineBRight);
+            elements.add(lineCRight);
+            elements.add(lineDRight);
+        }
+        if (showArrow(RIGHT_CENTER)) {
+            elements.add(lineERight);
+            elements.add(lineFRight);
+            elements.add(lineGRight);
+        }
+        if (showArrow(RIGHT_BOTTOM)) {
+            elements.add(lineHRight);
+            elements.add(lineIRight);
+            elements.add(lineJRight);
+        }
+        elements.add(lineKRight);
+        elements.add(bottomCurveTo);
+
+        if (showArrow(BOTTOM_RIGHT)) {
+            elements.add(lineBBottom);
+            elements.add(lineCBottom);
+            elements.add(lineDBottom);
+        }
+        if (showArrow(BOTTOM_CENTER)) {
+            elements.add(lineEBottom);
+            elements.add(lineFBottom);
+            elements.add(lineGBottom);
+        }
+        if (showArrow(BOTTOM_LEFT)) {
+            elements.add(lineHBottom);
+            elements.add(lineIBottom);
+            elements.add(lineJBottom);
+        }
+        elements.add(lineKBottom);
+        elements.add(leftCurveTo);
+
+        if (showArrow(LEFT_BOTTOM)) {
+            elements.add(lineBLeft);
+            elements.add(lineCLeft);
+            elements.add(lineDLeft);
+        }
+        if (showArrow(LEFT_CENTER)) {
+            elements.add(lineELeft);
+            elements.add(lineFLeft);
+            elements.add(lineGLeft);
+        }
+        if (showArrow(LEFT_TOP)) {
+            elements.add(lineHLeft);
+            elements.add(lineILeft);
+            elements.add(lineJLeft);
+        }
+        elements.add(lineKLeft);
+        elements.add(topCurveTo);
+
+        path.getElements().setAll(elements);
+        clip.getElements().setAll(elements);
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/PropertySheetSkin.java b/src/impl/org/controlsfx/skin/PropertySheetSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..f050288b4bc85a4ec2d4b2f4ecc57fa15bd40970
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/PropertySheetSkin.java
@@ -0,0 +1,350 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import static impl.org.controlsfx.i18n.Localization.asKey;
+import static impl.org.controlsfx.i18n.Localization.localize;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ListChangeListener;
+import javafx.geometry.Insets;
+import javafx.scene.Node;
+import javafx.scene.control.Accordion;
+import javafx.scene.control.Label;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TitledPane;
+import javafx.scene.control.ToolBar;
+import javafx.scene.control.Tooltip;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.Region;
+
+import org.controlsfx.control.PropertySheet;
+import org.controlsfx.control.PropertySheet.Item;
+import org.controlsfx.control.PropertySheet.Mode;
+import org.controlsfx.control.SegmentedButton;
+import org.controlsfx.control.action.Action;
+import org.controlsfx.control.action.ActionUtils;
+import org.controlsfx.control.textfield.TextFields;
+import org.controlsfx.property.editor.AbstractPropertyEditor;
+import org.controlsfx.property.editor.PropertyEditor;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+
+public class PropertySheetSkin extends BehaviorSkinBase<PropertySheet, BehaviorBase<PropertySheet>> {
+    
+    /**************************************************************************
+     * 
+     * Static fields
+     * 
+     **************************************************************************/
+
+    private static final int MIN_COLUMN_WIDTH = 100;
+    
+    /**************************************************************************
+     * 
+     * fields
+     * 
+     **************************************************************************/
+    
+    private final BorderPane content;
+    private final ScrollPane scroller;
+    private final ToolBar toolbar;
+    private final SegmentedButton modeButton = ActionUtils.createSegmentedButton(
+        new ActionChangeMode(Mode.NAME),
+        new ActionChangeMode(Mode.CATEGORY)
+    );
+    private final TextField searchField = TextFields.createClearableTextField();
+    
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+
+    public PropertySheetSkin(final PropertySheet control) {
+        super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
+        
+        scroller = new ScrollPane();
+        scroller.setFitToWidth(true);
+        
+        toolbar = new ToolBar();
+        toolbar.managedProperty().bind(toolbar.visibleProperty());
+        toolbar.setFocusTraversable(true);
+        
+        // property sheet mode
+        modeButton.managedProperty().bind(modeButton.visibleProperty());
+        modeButton.getButtons().get(getSkinnable().modeProperty().get().ordinal()).setSelected(true);
+        toolbar.getItems().add(modeButton);
+        
+        // property sheet search
+        searchField.setPromptText( localize(asKey("property.sheet.search.field.prompt"))); //$NON-NLS-1$
+        searchField.setMinWidth(0);
+        HBox.setHgrow(searchField, Priority.SOMETIMES);
+        searchField.managedProperty().bind(searchField.visibleProperty());
+        toolbar.getItems().add(searchField);
+        
+        // layout controls
+        content = new BorderPane();
+        content.setTop(toolbar);
+        content.setCenter(scroller);
+        getChildren().add(content);
+              
+        
+        // setup listeners
+        registerChangeListener(control.modeProperty(), "MODE"); //$NON-NLS-1$
+        registerChangeListener(control.propertyEditorFactory(), "EDITOR-FACTORY"); //$NON-NLS-1$
+        registerChangeListener(control.titleFilter(), "FILTER"); //$NON-NLS-1$
+        registerChangeListener(searchField.textProperty(), "FILTER-UI"); //$NON-NLS-1$
+        registerChangeListener(control.modeSwitcherVisibleProperty(), "TOOLBAR-MODE"); //$NON-NLS-1$
+        registerChangeListener(control.searchBoxVisibleProperty(), "TOOLBAR-SEARCH"); //$NON-NLS-1$
+        
+        control.getItems().addListener((ListChangeListener<Item>) change -> refreshProperties());
+        
+        // initialize properly 
+        refreshProperties(); 
+        updateToolbar();
+    }
+
+
+    /**************************************************************************
+     * 
+     * Overriding public API
+     * 
+     **************************************************************************/
+
+    @Override protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+        
+        if (p == "MODE" || p == "EDITOR-FACTORY" || p == "FILTER") { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            refreshProperties();
+        } else if (p == "FILTER-UI") { //$NON-NLS-1$
+            getSkinnable().setTitleFilter(searchField.getText());
+        } else if (p == "TOOLBAR-MODE") { //$NON-NLS-1$
+            updateToolbar();
+        } else if (p == "TOOLBAR-SEARCH") { //$NON-NLS-1$
+            updateToolbar();
+        }
+    }
+    
+    @Override protected void layoutChildren(double x, double y, double w, double h) {
+        content.resizeRelocate(x, y, w, h);
+    }
+
+
+
+    /**************************************************************************
+     * 
+     * Implementation
+     * 
+     **************************************************************************/
+    
+    private void updateToolbar() {
+        modeButton.setVisible(getSkinnable().isModeSwitcherVisible());
+        searchField.setVisible(getSkinnable().isSearchBoxVisible());
+        
+        toolbar.setVisible(modeButton.isVisible() || searchField.isVisible());
+    }
+
+    private void refreshProperties() {
+        scroller.setContent(buildPropertySheetContainer());
+    }
+    
+    private Node buildPropertySheetContainer() {
+        switch( getSkinnable().modeProperty().get() ) {
+            case CATEGORY: {
+                // group by category
+                Map<String, List<Item>> categoryMap = new TreeMap<>();
+                for( Item p: getSkinnable().getItems()) {
+                    String category = p.getCategory();
+                    List<Item> list = categoryMap.get(category);
+                    if ( list == null ) {
+                        list = new ArrayList<>();
+                        categoryMap.put( category, list);
+                    }
+                    list.add(p);
+                }
+                
+                // create category-based accordion
+                Accordion accordion = new Accordion();
+                for( String category: categoryMap.keySet() ) {
+                	PropertyPane props = new PropertyPane( categoryMap.get(category));
+                	// Only show non-empty categories 
+                	if ( props.getChildrenUnmodifiable().size() > 0 ) {
+                       TitledPane pane = new TitledPane( category, props );
+                       pane.setExpanded(true);
+                       accordion.getPanes().add(pane);
+                    }
+                }
+                if ( accordion.getPanes().size() > 0 ) {
+                    accordion.setExpandedPane(accordion.getPanes().get(0));
+                }
+                return accordion;
+            }
+            
+            default: return new PropertyPane(getSkinnable().getItems());
+        }
+        
+    }
+
+    
+    /**************************************************************************
+     * 
+     * Support classes / enums
+     * 
+     **************************************************************************/
+    
+    private class ActionChangeMode extends Action {
+        
+    	private final Image CATEGORY_IMAGE = new Image(PropertySheetSkin.class.getResource("/org/controlsfx/control/format-indent-more.png").toExternalForm()); //$NON-NLS-1$
+    	private final Image NAME_IMAGE = new Image(PropertySheetSkin.class.getResource("/org/controlsfx/control/format-line-spacing-triple.png").toExternalForm()); //$NON-NLS-1$
+    	
+        public ActionChangeMode(PropertySheet.Mode mode) {
+            super(""); //$NON-NLS-1$
+            setEventHandler(ae -> getSkinnable().modeProperty().set(mode));
+            
+            if (mode == Mode.CATEGORY) {
+                setGraphic( new ImageView(CATEGORY_IMAGE));
+                setLongText(localize(asKey("property.sheet.group.mode.bycategory"))); //$NON-NLS-1$
+            } else if (mode == Mode.NAME) {
+                setGraphic(new ImageView(NAME_IMAGE));
+                setLongText(localize(asKey("property.sheet.group.mode.byname"))); //$NON-NLS-1$
+            } else {
+                setText("???"); //$NON-NLS-1$
+            }
+        }
+
+    }
+    
+    
+    private class PropertyPane extends GridPane {
+        
+        public PropertyPane( List<Item> properties ) {
+            this( properties, 0 );
+        }
+        
+        public PropertyPane( List<Item> properties, int nestingLevel ) {
+            setVgap(5);
+            setHgap(5);
+            setPadding(new Insets(5, 15, 5, 15 + nestingLevel*10 ));
+            getStyleClass().add("property-pane"); //$NON-NLS-1$
+            setItems(properties);
+//            setGridLinesVisible(true);
+        }
+        
+        public void setItems( List<Item> properties ) {
+            getChildren().clear();
+            
+            String filter = getSkinnable().titleFilter().get();
+            filter = filter == null? "": filter.trim().toLowerCase(); //$NON-NLS-1$
+
+            int row = 0;
+            
+            for (Item item : properties) {
+
+                // filter properties
+                String title = item.getName();
+               
+                if ( !filter.isEmpty() && title.toLowerCase().indexOf( filter ) < 0) continue;
+                
+                // setup property label
+                Label label = new Label(title);
+                label.setMinWidth(MIN_COLUMN_WIDTH);
+                
+                // show description as a tooltip
+                String description = item.getDescription();
+                if ( description != null && !description.trim().isEmpty()) {
+                    label.setTooltip(new Tooltip(description));
+                }
+                
+                add(label, 0, row);
+
+                // setup property editor
+                Node editor = getEditor(item);
+                
+                if (editor instanceof Region) {
+                    ((Region)editor).setMinWidth(MIN_COLUMN_WIDTH);
+                    ((Region)editor).setMaxWidth(Double.MAX_VALUE);
+                }
+                label.setLabelFor(editor);
+                add(editor, 1, row);
+                GridPane.setHgrow(editor, Priority.ALWAYS);
+                
+                //TODO add support for recursive properties
+                
+                row++;
+            }
+            
+        }
+        
+        @SuppressWarnings("unchecked")
+        private Node getEditor(Item item) {
+            @SuppressWarnings("rawtypes")
+            PropertyEditor editor = getSkinnable().getPropertyEditorFactory().call(item);
+            if (editor == null) {
+                editor = new AbstractPropertyEditor<Object, TextField>(item, new TextField(), true) {
+                    {
+                        getEditor().setEditable(false);
+                        getEditor().setDisable(true);
+                    }
+                    
+                    /**
+                     * {@inheritDoc}
+                     */
+                    @Override protected ObservableValue<Object> getObservableValue() {
+                        return (ObservableValue<Object>)(Object)getEditor().textProperty();
+                    }
+                    
+                    /**
+                     * {@inheritDoc}
+                     */
+                    @Override public void setValue(Object value) {
+                        getEditor().setText(value == null? "": value.toString()); //$NON-NLS-1$
+                    }
+                };
+            } else if (! item.isEditable()) {
+                editor.getEditor().setDisable(true);
+            }
+            editor.setValue(item.getValue());
+            return editor.getEditor();
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/RangeSliderSkin.java b/src/impl/org/controlsfx/skin/RangeSliderSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b324924b5e4516671b856c4dbf2e29fdb90463b
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/RangeSliderSkin.java
@@ -0,0 +1,580 @@
+/**
+ * Copyright (c) 2013, 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import static impl.org.controlsfx.behavior.RangeSliderBehavior.FocusedChild.HIGH_THUMB;
+import static impl.org.controlsfx.behavior.RangeSliderBehavior.FocusedChild.LOW_THUMB;
+import static impl.org.controlsfx.behavior.RangeSliderBehavior.FocusedChild.NONE;
+import static impl.org.controlsfx.behavior.RangeSliderBehavior.FocusedChild.RANGE_BAR;
+import impl.org.controlsfx.behavior.RangeSliderBehavior;
+import impl.org.controlsfx.behavior.RangeSliderBehavior.FocusedChild;
+import javafx.beans.binding.ObjectBinding;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.EventHandler;
+import javafx.geometry.Orientation;
+import javafx.geometry.Point2D;
+import javafx.geometry.Side;
+import javafx.scene.Cursor;
+import javafx.scene.chart.NumberAxis;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.StackPane;
+import javafx.util.Callback;
+
+import org.controlsfx.control.RangeSlider;
+
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+import com.sun.javafx.scene.traversal.Direction;
+import com.sun.javafx.scene.traversal.ParentTraversalEngine;
+
+public class RangeSliderSkin extends BehaviorSkinBase<RangeSlider, RangeSliderBehavior> {
+        
+    /** Track if slider is vertical/horizontal and cause re layout */
+    private NumberAxis tickLine = null;
+    private double trackToTickGap = 2;
+
+    private boolean showTickMarks;
+    private double thumbWidth;
+    private double thumbHeight;
+    
+    private Orientation orientation;
+
+    private StackPane track;
+    private double trackStart;
+    private double trackLength;
+    private double lowThumbPos;
+    private double rangeEnd;
+    private double rangeStart;
+    private ThumbPane lowThumb;
+    private ThumbPane highThumb;
+    private StackPane rangeBar; // the bar between the two thumbs, can be dragged
+    
+    // temp fields for mouse drag handling
+    private double preDragPos;          // used as a temp value for low and high thumbs
+    private Point2D preDragThumbPoint;  // in skin coordinates
+    
+    private FocusedChild currentFocus = LOW_THUMB;
+    
+    public RangeSliderSkin(final RangeSlider rangeSlider) {
+        super(rangeSlider, new RangeSliderBehavior(rangeSlider));
+        orientation = getSkinnable().getOrientation();
+        initFirstThumb();
+        initSecondThumb();
+        initRangeBar();
+        registerChangeListener(rangeSlider.lowValueProperty(), "LOW_VALUE"); //$NON-NLS-1$
+        registerChangeListener(rangeSlider.highValueProperty(), "HIGH_VALUE"); //$NON-NLS-1$
+        registerChangeListener(rangeSlider.minProperty(), "MIN"); //$NON-NLS-1$
+        registerChangeListener(rangeSlider.maxProperty(), "MAX"); //$NON-NLS-1$
+        registerChangeListener(rangeSlider.orientationProperty(), "ORIENTATION"); //$NON-NLS-1$
+        registerChangeListener(rangeSlider.showTickMarksProperty(), "SHOW_TICK_MARKS"); //$NON-NLS-1$
+        registerChangeListener(rangeSlider.showTickLabelsProperty(), "SHOW_TICK_LABELS"); //$NON-NLS-1$
+        registerChangeListener(rangeSlider.majorTickUnitProperty(), "MAJOR_TICK_UNIT"); //$NON-NLS-1$
+        registerChangeListener(rangeSlider.minorTickCountProperty(), "MINOR_TICK_COUNT"); //$NON-NLS-1$
+        lowThumb.focusedProperty().addListener(new ChangeListener<Boolean>() {
+            @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean hasFocus) {
+                if (hasFocus) {
+                    currentFocus = LOW_THUMB;
+                }
+            }
+        });
+        highThumb.focusedProperty().addListener(new ChangeListener<Boolean>() {
+            @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean hasFocus) {
+                if (hasFocus) {
+                    currentFocus = HIGH_THUMB;
+                }
+            }
+        });
+        rangeBar.focusedProperty().addListener(new ChangeListener<Boolean>() {
+            @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean hasFocus) {
+                if (hasFocus) {
+                    currentFocus = RANGE_BAR;
+                }
+            }
+        });
+        rangeSlider.focusedProperty().addListener(new ChangeListener<Boolean>() {
+            @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean hasFocus) {
+                if (hasFocus) {
+                    lowThumb.setFocus(true);
+                } else {
+                    lowThumb.setFocus(false);
+                    highThumb.setFocus(false);
+                    currentFocus = NONE;
+                }
+            }
+        });
+
+        EventHandler<KeyEvent> keyEventHandler = new EventHandler<KeyEvent>() {
+            @Override public void handle(KeyEvent event) {
+                if (KeyCode.TAB.equals(event.getCode())) {
+                    if (lowThumb.isFocused()) {
+                        if (event.isShiftDown()) {
+                            lowThumb.setFocus(false);
+                            new ParentTraversalEngine(rangeSlider).select(rangeSlider, Direction.PREVIOUS);
+                        } else {
+                            lowThumb.setFocus(false);
+                            highThumb.setFocus(true);
+                        }
+                        event.consume();
+                    } else if (highThumb.isFocused()) {
+                        if(event.isShiftDown()) {
+                            highThumb.setFocus(false);
+                            lowThumb.setFocus(true);
+                        } else {
+                            highThumb.setFocus(false);
+                            new ParentTraversalEngine(rangeSlider).select(rangeSlider, Direction.NEXT);
+                        }
+                        event.consume();
+                    }
+                }
+            }
+        };
+        getSkinnable().addEventHandler(KeyEvent.KEY_PRESSED, keyEventHandler);  
+        // set up a callback on the behavior to indicate which thumb is currently 
+        // selected (via enum).
+        getBehavior().setSelectedValue(new Callback<Void, FocusedChild>() {
+            @Override public FocusedChild call(Void v) {
+                return currentFocus;
+            }
+        });
+    }
+    
+    private void initFirstThumb() {
+        lowThumb = new ThumbPane();
+        lowThumb.getStyleClass().setAll("low-thumb"); //$NON-NLS-1$
+        lowThumb.setFocusTraversable(true);
+        track = new StackPane();
+        track.getStyleClass().setAll("track"); //$NON-NLS-1$
+
+        getChildren().clear();
+        getChildren().addAll(track, lowThumb);
+        setShowTickMarks(getSkinnable().isShowTickMarks(), getSkinnable().isShowTickLabels());
+        track.setOnMousePressed( new EventHandler<javafx.scene.input.MouseEvent>() {
+            @Override public void handle(javafx.scene.input.MouseEvent me) {
+                if (!lowThumb.isPressed() && !highThumb.isPressed()) {
+                    if (isHorizontal()) {
+                        getBehavior().trackPress(me, (me.getX() / trackLength));
+                    } else {
+                        getBehavior().trackPress(me, (me.getY() / trackLength));
+                    }
+                }
+            }
+        });
+
+        track.setOnMouseReleased( new EventHandler<javafx.scene.input.MouseEvent>() {
+            @Override public void handle(javafx.scene.input.MouseEvent me) {
+                 //Nothing being done with the second param in sliderBehavior
+                //So, passing a dummy value
+                getBehavior().trackRelease(me, 0.0f);
+            }
+        });
+
+        lowThumb.setOnMousePressed(new EventHandler<javafx.scene.input.MouseEvent>() {
+            @Override public void handle(javafx.scene.input.MouseEvent me) {
+                highThumb.setFocus(false);
+                lowThumb.setFocus(true);
+                getBehavior().lowThumbPressed(me, 0.0f);
+                preDragThumbPoint = lowThumb.localToParent(me.getX(), me.getY());
+                preDragPos = (getSkinnable().getLowValue() - getSkinnable().getMin()) /
+                        (getMaxMinusMinNoZero());
+            }
+        });
+
+        lowThumb.setOnMouseReleased(new EventHandler<javafx.scene.input.MouseEvent>() {
+            @Override public void handle(javafx.scene.input.MouseEvent me) {
+                getBehavior().lowThumbReleased(me);
+            }
+        });
+
+        lowThumb.setOnMouseDragged(new EventHandler<javafx.scene.input.MouseEvent>() {
+            @Override public void handle(javafx.scene.input.MouseEvent me) {
+                Point2D cur = lowThumb.localToParent(me.getX(), me.getY());
+                double dragPos = (isHorizontal())?
+                    cur.getX() - preDragThumbPoint.getX() : -(cur.getY() - preDragThumbPoint.getY());
+                getBehavior().lowThumbDragged(me, preDragPos + dragPos / trackLength);
+            }
+        });
+    }
+
+    private void initSecondThumb() {
+        highThumb = new ThumbPane();
+        highThumb.getStyleClass().setAll("high-thumb"); //$NON-NLS-1$
+        highThumb.setFocusTraversable(true);
+        if (!getChildren().contains(highThumb)) {
+            getChildren().add(highThumb);
+        }
+
+        highThumb.setOnMousePressed(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent e) {
+                lowThumb.setFocus(false);
+                highThumb.setFocus(true);
+                ((RangeSliderBehavior) getBehavior()).highThumbPressed(e, 0.0D);
+                preDragThumbPoint = highThumb.localToParent(e.getX(), e.getY());
+                preDragPos = (((RangeSlider) getSkinnable()).getHighValue() - ((RangeSlider) getSkinnable()).getMin()) / 
+                            (getMaxMinusMinNoZero());
+            }
+        }
+        );
+        highThumb.setOnMouseReleased(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent e) {
+                ((RangeSliderBehavior) getBehavior()).highThumbReleased(e);
+            }
+        }
+        );
+        highThumb.setOnMouseDragged(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent e) {
+                boolean orientation = ((RangeSlider) getSkinnable()).getOrientation() == Orientation.HORIZONTAL;
+                double trackLength = orientation ? track.getWidth() : track.getHeight();
+
+                Point2D point2d = highThumb.localToParent(e.getX(), e.getY());
+                double d = ((RangeSlider) getSkinnable()).getOrientation() != Orientation.HORIZONTAL ? -(point2d.getY() - preDragThumbPoint.getY()) : point2d.getX() - preDragThumbPoint.getX();
+                ((RangeSliderBehavior) getBehavior()).highThumbDragged(e, preDragPos + d / trackLength);
+            }
+        });
+    }
+    
+    private void initRangeBar() {
+        rangeBar = new StackPane();
+        rangeBar.cursorProperty().bind(new ObjectBinding<Cursor>() {
+            { bind(rangeBar.hoverProperty()); }
+
+            @Override protected Cursor computeValue() {
+                return rangeBar.isHover() ? Cursor.HAND : Cursor.DEFAULT;
+            }
+        });
+        rangeBar.getStyleClass().setAll("range-bar"); //$NON-NLS-1$
+        
+        rangeBar.setOnMousePressed(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent e) {
+                rangeBar.requestFocus();
+                preDragPos = isHorizontal() ? e.getX() : -e.getY();
+            }
+        });
+        
+        rangeBar.setOnMouseDragged(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent e) {
+                double delta = (isHorizontal() ? e.getX() : -e.getY()) - preDragPos;
+                ((RangeSliderBehavior) getBehavior()).moveRange(delta);
+            }
+        });
+        
+         rangeBar.setOnMouseReleased(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent e) {
+                ((RangeSliderBehavior) getBehavior()).confirmRange();
+            }
+        });
+        
+        getChildren().add(rangeBar);
+    }
+
+    /**
+     * When ticks or labels are changing of visibility, we compute the new
+     * visibility and add the necessary objets. After this method, we must be
+     * sure to add the high Thumb and the rangeBar.
+     *
+     * @param ticksVisible
+     * @param labelsVisible
+     */
+    private void setShowTickMarks(boolean ticksVisible, boolean labelsVisible) {
+        showTickMarks = (ticksVisible || labelsVisible);
+        RangeSlider rangeSlider = getSkinnable();
+        if (showTickMarks) {
+            if (tickLine == null) {
+                tickLine = new NumberAxis();
+                tickLine.tickLabelFormatterProperty().bind(getSkinnable().labelFormatterProperty());
+                tickLine.setAnimated(false);
+                tickLine.setAutoRanging(false);
+                tickLine.setSide(isHorizontal() ? Side.BOTTOM : Side.RIGHT);
+                tickLine.setUpperBound(rangeSlider.getMax());
+                tickLine.setLowerBound(rangeSlider.getMin());
+                tickLine.setTickUnit(rangeSlider.getMajorTickUnit());
+                tickLine.setTickMarkVisible(ticksVisible);
+                tickLine.setTickLabelsVisible(labelsVisible);
+                tickLine.setMinorTickVisible(ticksVisible);
+                // add 1 to the slider minor tick count since the axis draws one
+                // less minor ticks than the number given.
+                tickLine.setMinorTickCount(Math.max(rangeSlider.getMinorTickCount(),0) + 1);
+                getChildren().clear();
+                getChildren().addAll(tickLine, track, lowThumb);
+            } else {
+                tickLine.setTickLabelsVisible(labelsVisible);
+                tickLine.setTickMarkVisible(ticksVisible);
+                tickLine.setMinorTickVisible(ticksVisible);
+            }
+        } 
+        else  {
+            getChildren().clear();
+            getChildren().addAll(track, lowThumb);
+//            tickLine = null;
+        }
+
+        getSkinnable().requestLayout();
+    }
+
+    @Override protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+        if ("ORIENTATION".equals(p)) { //$NON-NLS-1$
+            orientation = getSkinnable().getOrientation();
+            if (showTickMarks && tickLine != null) {
+                tickLine.setSide(isHorizontal() ? Side.BOTTOM : Side.RIGHT);
+            }
+            getSkinnable().requestLayout();
+        } else if ("MIN".equals(p) ) { //$NON-NLS-1$
+            if (showTickMarks && tickLine != null) {
+                tickLine.setLowerBound(getSkinnable().getMin());
+            }
+            getSkinnable().requestLayout();
+        } else if ("MAX".equals(p)) { //$NON-NLS-1$
+            if (showTickMarks && tickLine != null) {
+                tickLine.setUpperBound(getSkinnable().getMax());
+            }
+            getSkinnable().requestLayout();
+        } else if ("SHOW_TICK_MARKS".equals(p) || "SHOW_TICK_LABELS".equals(p)) { //$NON-NLS-1$ //$NON-NLS-2$
+            setShowTickMarks(getSkinnable().isShowTickMarks(), getSkinnable().isShowTickLabels());
+            if (!getChildren().contains(highThumb))
+                getChildren().add(highThumb);
+            if (!getChildren().contains(rangeBar))
+                getChildren().add(rangeBar);
+        }  else if ("MAJOR_TICK_UNIT".equals(p)) { //$NON-NLS-1$
+            if (tickLine != null) {
+                tickLine.setTickUnit(getSkinnable().getMajorTickUnit());
+                getSkinnable().requestLayout();
+            }
+        } else if ("MINOR_TICK_COUNT".equals(p)) { //$NON-NLS-1$
+            if (tickLine != null) {
+                tickLine.setMinorTickCount(Math.max(getSkinnable().getMinorTickCount(),0) + 1);
+                getSkinnable().requestLayout();
+            }
+        } else if ("LOW_VALUE".equals(p)) { //$NON-NLS-1$
+            positionLowThumb();
+            rangeBar.resizeRelocate(rangeStart, rangeBar.getLayoutY(), 
+                    rangeEnd - rangeStart, rangeBar.getHeight());
+        } else if ("HIGH_VALUE".equals(p)) { //$NON-NLS-1$
+            positionHighThumb();
+            rangeBar.resize(rangeEnd-rangeStart, rangeBar.getHeight());
+        }
+        super.handleControlPropertyChanged(p);
+    }
+    
+    /**
+     *
+     * @return the difference between max and min, but if they have the same
+     * value, 1 is returned instead of 0 because otherwise the division where it
+     * can be used will return Nan.
+     */
+    private double getMaxMinusMinNoZero() {
+        RangeSlider s = getSkinnable();
+        return s.getMax() - s.getMin() == 0 ? 1 : s.getMax() - s.getMin();
+    }
+    
+    /**
+     * Called when ever either min, max or lowValue changes, so lowthumb's layoutX, Y is recomputed.
+     */
+    private void positionLowThumb() {
+        RangeSlider s = getSkinnable();
+        boolean horizontal = isHorizontal();
+        double lx = (horizontal) ? trackStart + (((trackLength * ((s.getLowValue() - s.getMin()) /
+                (getMaxMinusMinNoZero()))) - thumbWidth/2)) : lowThumbPos;
+        double ly = (horizontal) ? lowThumbPos :
+            getSkinnable().getInsets().getTop() + trackLength - (trackLength * ((s.getLowValue() - s.getMin()) /
+                (getMaxMinusMinNoZero()))); //  - thumbHeight/2
+        lowThumb.setLayoutX(lx);
+        lowThumb.setLayoutY(ly);
+        if (horizontal) rangeStart = lx + thumbWidth; else rangeEnd = ly;
+    }
+
+    /**
+     * Called when ever either min, max or highValue changes, so highthumb's layoutX, Y is recomputed.
+     */
+    private void positionHighThumb() {
+        RangeSlider slider = (RangeSlider) getSkinnable();
+        boolean orientation = ((RangeSlider) getSkinnable()).getOrientation() == Orientation.HORIZONTAL;
+
+        double thumbWidth = lowThumb.getWidth();
+        double thumbHeight = lowThumb.getHeight();
+        highThumb.resize(thumbWidth, thumbHeight);
+
+        double pad = 0;//track.impl_getBackgroundFills() == null || track.impl_getBackgroundFills().length <= 0 ? 0.0D : track.impl_getBackgroundFills()[0].getTopLeftCornerRadius();
+        double trackStart = orientation ? track.getLayoutX() : track.getLayoutY();
+        trackStart += pad;
+        double trackLength = orientation ? track.getWidth() : track.getHeight();
+        trackLength -= 2 * pad;
+
+        double x = orientation ? trackStart + (trackLength * ((slider.getHighValue() - slider.getMin()) / (getMaxMinusMinNoZero())) - thumbWidth / 2D) : lowThumb.getLayoutX();
+        double y = orientation ? lowThumb.getLayoutY() : (getSkinnable().getInsets().getTop() + trackLength) - trackLength * ((slider.getHighValue() - slider.getMin()) / (getMaxMinusMinNoZero()));
+        highThumb.setLayoutX(x);
+        highThumb.setLayoutY(y);
+        if (orientation) rangeEnd = x; else rangeStart = y + thumbWidth;
+    }
+    
+    @Override protected void layoutChildren(final double x, final double y,
+            final double w, final double h) {
+        // resize thumb to preferred size
+        thumbWidth = lowThumb.prefWidth(-1);
+        thumbHeight = lowThumb.prefHeight(-1);
+        lowThumb.resize(thumbWidth, thumbHeight);
+        // we are assuming the is common radius's for all corners on the track
+        double trackRadius = track.getBackground() == null ? 0 : track.getBackground().getFills().size() > 0 ?
+                track.getBackground().getFills().get(0).getRadii().getTopLeftHorizontalRadius() : 0;
+      
+        if (isHorizontal()) {
+            double tickLineHeight =  (showTickMarks) ? tickLine.prefHeight(-1) : 0;
+            double trackHeight = track.prefHeight(-1);
+            double trackAreaHeight = Math.max(trackHeight,thumbHeight);
+            double totalHeightNeeded = trackAreaHeight  + ((showTickMarks) ? trackToTickGap+tickLineHeight : 0);
+            double startY = y + ((h - totalHeightNeeded)/2); // center slider in available height vertically
+            trackLength = w - thumbWidth;
+            trackStart = x + (thumbWidth/2);
+            double trackTop = (int)(startY + ((trackAreaHeight-trackHeight)/2));
+            lowThumbPos = (int)(startY + ((trackAreaHeight-thumbHeight)/2));
+            
+            positionLowThumb();
+            // layout track
+            track.resizeRelocate(trackStart - trackRadius, trackTop , trackLength + trackRadius + trackRadius, trackHeight);
+            positionHighThumb();
+            // layout range bar
+            rangeBar.resizeRelocate(rangeStart, trackTop, rangeEnd - rangeStart, trackHeight);
+            // layout tick line
+            if (showTickMarks) {
+                tickLine.setLayoutX(trackStart);
+                tickLine.setLayoutY(trackTop+trackHeight+trackToTickGap);
+                tickLine.resize(trackLength, tickLineHeight);
+                tickLine.requestAxisLayout();
+            } else {
+                if (tickLine != null) {
+                    tickLine.resize(0,0);
+                    tickLine.requestAxisLayout();
+                }
+                tickLine = null;
+            }
+        } else {
+            double tickLineWidth = (showTickMarks) ? tickLine.prefWidth(-1) : 0;
+            double trackWidth = track.prefWidth(-1);
+            double trackAreaWidth = Math.max(trackWidth,thumbWidth);
+            double totalWidthNeeded = trackAreaWidth  + ((showTickMarks) ? trackToTickGap+tickLineWidth : 0) ;
+            double startX = x + ((w - totalWidthNeeded)/2); // center slider in available width horizontally
+            trackLength = h - thumbHeight;
+            trackStart = y + (thumbHeight/2);
+            double trackLeft = (int)(startX + ((trackAreaWidth-trackWidth)/2));
+            lowThumbPos = (int)(startX + ((trackAreaWidth-thumbWidth)/2));
+
+            positionLowThumb();
+            // layout track
+            track.resizeRelocate(trackLeft, trackStart - trackRadius, trackWidth, trackLength + trackRadius + trackRadius);
+            positionHighThumb();
+            // layout range bar
+            rangeBar.resizeRelocate(trackLeft, rangeStart, trackWidth, rangeEnd - rangeStart);
+            // layout tick line
+            if (showTickMarks) {
+                tickLine.setLayoutX(trackLeft+trackWidth+trackToTickGap);
+                tickLine.setLayoutY(trackStart);
+                tickLine.resize(tickLineWidth, trackLength);
+                tickLine.requestAxisLayout();
+            } else {
+                if (tickLine != null) {
+                    tickLine.resize(0,0);
+                    tickLine.requestAxisLayout();
+                }
+                tickLine = null;
+            }
+        }
+    }
+    
+    private double minTrackLength() {
+        return 2*lowThumb.prefWidth(-1);
+    }
+    
+    @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        if (isHorizontal()) {
+            return (leftInset + minTrackLength() + lowThumb.minWidth(-1) + rightInset);
+        } else {
+            return (leftInset + lowThumb.prefWidth(-1) + rightInset);
+        }
+    }
+
+    @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+         if (isHorizontal()) {
+            return (topInset + lowThumb.prefHeight(-1) + bottomInset);
+        } else {
+            return (topInset + minTrackLength() + lowThumb.prefHeight(-1) + bottomInset);
+        }
+    }
+
+    @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        if (isHorizontal()) {
+            if(showTickMarks) {
+                return Math.max(140, tickLine.prefWidth(-1));
+            } else {
+                return 140;
+            }
+        } else {
+            //return (padding.getLeft()) + Math.max(thumb.prefWidth(-1), track.prefWidth(-1)) + padding.getRight();
+            return leftInset + Math.max(lowThumb.prefWidth(-1), track.prefWidth(-1)) +
+            ((showTickMarks) ? (trackToTickGap+tickLine.prefWidth(-1)) : 0) + rightInset;
+        }
+    }
+
+    @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        if (isHorizontal()) {
+            return getSkinnable().getInsets().getTop() + Math.max(lowThumb.prefHeight(-1), track.prefHeight(-1)) +
+             ((showTickMarks) ? (trackToTickGap+tickLine.prefHeight(-1)) : 0)  + bottomInset;
+        } else {
+            if(showTickMarks) {
+                return Math.max(140, tickLine.prefHeight(-1));
+            } else {
+                return 140;
+            }
+        }
+    }
+
+    @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        if (isHorizontal()) {
+            return Double.MAX_VALUE;
+        } else {
+            return getSkinnable().prefWidth(-1);
+        }
+    }
+
+    @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        if (isHorizontal()) {
+            return getSkinnable().prefHeight(width);
+        } else {
+            return Double.MAX_VALUE;
+        }
+    }
+    
+    private boolean isHorizontal() {
+        return orientation == null || orientation == Orientation.HORIZONTAL;
+    }
+
+    private static class ThumbPane extends StackPane {
+        public void setFocus(boolean value) {
+            setFocused(value);
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/RatingSkin.java b/src/impl/org/controlsfx/skin/RatingSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c13fc31320e3f6bbdf06324dd83d4bd4122d0b5
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/RatingSkin.java
@@ -0,0 +1,329 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import impl.org.controlsfx.behavior.RatingBehavior;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javafx.event.EventHandler;
+import javafx.geometry.Orientation;
+import javafx.geometry.Point2D;
+import javafx.scene.Node;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.VBox;
+import javafx.scene.shape.Rectangle;
+
+import org.controlsfx.control.Rating;
+import org.controlsfx.tools.Utils;
+
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+
+/**
+ *
+ */
+public class RatingSkin extends BehaviorSkinBase<Rating, RatingBehavior> {
+        
+    /***************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+    private static final String STRONG = "strong"; //$NON-NLS-1$
+    
+    private boolean updateOnHover;
+    private boolean partialRating;
+    
+    // the container for the traditional rating control. If updateOnHover and
+    // partialClipping are disabled, this will show a combination of strong
+    // and non-strong graphics, depending on the current rating value
+    private Pane backgroundContainer;
+    
+    // the container for the strong graphics which may be partially clipped.
+    // Note that this only exists if updateOnHover or partialClipping is enabled.
+    private Pane foregroundContainer;
+    
+    private double rating = -1;
+
+    private Rectangle forgroundClipRect;
+        
+    private final EventHandler<MouseEvent> mouseMoveHandler = new EventHandler<MouseEvent>() {
+        @Override public void handle(MouseEvent event) {
+
+        	// if we support updateOnHover, calculate the intended rating based on the mouse 
+        	// location and update the control property with it.
+        	
+            if (updateOnHover) {
+            	updateRatingFromMouseEvent(event);
+            }
+        }
+    };
+    
+    private final EventHandler<MouseEvent> mouseClickHandler = new EventHandler<MouseEvent>() {
+        @Override public void handle(MouseEvent event) {
+
+        	// if we are not updating on hover, calculate the intended rating based on the mouse 
+        	// location and update the control property with it.
+        	
+            if (! updateOnHover) {
+            	updateRatingFromMouseEvent(event);
+            }
+        }
+    };
+    
+    private void updateRatingFromMouseEvent(MouseEvent event) {
+    	Rating control = getSkinnable();
+    	if (! control.ratingProperty().isBound()) {
+        	Point2D mouseLocation = new Point2D(event.getSceneX(), event.getSceneY());
+    		control.setRating(calculateRating(mouseLocation));
+    	}
+    }
+
+    /***************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    public RatingSkin(Rating control) {
+        super(control, new RatingBehavior(control));
+        
+        this.updateOnHover = control.isUpdateOnHover();
+        this.partialRating = control.isPartialRating();
+        
+        // init
+        recreateButtons();
+        updateRating();
+        // -- end init
+        
+        registerChangeListener(control.ratingProperty(), "RATING"); //$NON-NLS-1$
+        registerChangeListener(control.maxProperty(), "MAX"); //$NON-NLS-1$
+        registerChangeListener(control.orientationProperty(), "ORIENTATION"); //$NON-NLS-1$
+        registerChangeListener(control.updateOnHoverProperty(), "UPDATE_ON_HOVER"); //$NON-NLS-1$
+        registerChangeListener(control.partialRatingProperty(), "PARTIAL_RATING"); //$NON-NLS-1$
+        // added to ensure clip is correctly calculated when control is first shown:
+        registerChangeListener(control.boundsInLocalProperty(), "BOUNDS"); //$NON-NLS-1$
+    }
+
+    
+    
+    /***************************************************************************
+     * 
+     * Implementation
+     * 
+     **************************************************************************/
+    
+    @Override protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+        
+        if (p == "RATING") { //$NON-NLS-1$
+            updateRating();
+        } else if (p == "MAX") { //$NON-NLS-1$
+            recreateButtons();
+        } else if (p == "ORIENTATION") { //$NON-NLS-1$
+            recreateButtons();
+        } else if (p == "PARTIAL_RATING") { //$NON-NLS-1$
+            this.partialRating = getSkinnable().isPartialRating();
+            recreateButtons();
+        } else if (p == "UPDATE_ON_HOVER") { //$NON-NLS-1$
+            this.updateOnHover = getSkinnable().isUpdateOnHover();
+            recreateButtons();
+        } else if (p == "BOUNDS") { //$NON-NLS-1$
+        	if (this.partialRating) {
+        		updateClip();
+        	}
+        }
+    }
+    
+    private void recreateButtons() {
+        backgroundContainer = null;
+        foregroundContainer = null;
+        
+        backgroundContainer = isVertical() ? new VBox() : new HBox();
+        backgroundContainer.getStyleClass().add("container"); //$NON-NLS-1$
+        getChildren().setAll(backgroundContainer);
+        
+        if (updateOnHover || partialRating) {
+            foregroundContainer = isVertical() ? new VBox() : new HBox();
+            foregroundContainer.getStyleClass().add("container"); //$NON-NLS-1$
+            foregroundContainer.setMouseTransparent(true);
+            getChildren().add(foregroundContainer);
+            
+            forgroundClipRect = new Rectangle();
+            foregroundContainer.setClip(forgroundClipRect);
+            
+        }
+        
+        for (int index = 0; index <= getSkinnable().getMax(); index++) {
+            Node backgroundNode = createButton();
+            
+            if (index > 0) {
+                if (isVertical()) {
+                    backgroundContainer.getChildren().add(0,backgroundNode);
+                } else {
+                    backgroundContainer.getChildren().add(backgroundNode);
+                }
+                
+                if (partialRating) {
+                    Node foregroundNode = createButton();
+                    foregroundNode.getStyleClass().add(STRONG);
+                    foregroundNode.setMouseTransparent(true);
+                    
+                    if (isVertical()) {
+                        foregroundContainer.getChildren().add(0,foregroundNode);
+                    } else {
+                        foregroundContainer.getChildren().add(foregroundNode);
+                    }
+                }
+            }
+        }
+        
+        updateRating();
+    }
+    
+    // Calculate the rating based on a mouse position (in Scene coordinates).
+    // If we support partial ratings, the value is calculated directly.
+    // Otherwise the ceil of the value is computed.
+    private double calculateRating(Point2D sceneLocation) {
+        final Point2D b = backgroundContainer.sceneToLocal(sceneLocation);
+        
+        final double x = b.getX();
+        final double y = b.getY();
+        
+        final Rating control = getSkinnable();
+        
+        final int max = control.getMax();
+        final double w = control.getWidth() - (snappedLeftInset() + snappedRightInset());
+        final double h = control.getHeight() - (snappedTopInset() + snappedBottomInset());
+        
+        double newRating = -1;
+        
+        if (isVertical()) {
+            newRating = ((h - y) / h) * max;
+        } else {
+            newRating = (x / w) * max;
+        }
+        
+        if (! partialRating) {
+            newRating = Utils.clamp(1, Math.ceil(newRating), control.getMax());
+        }
+        
+        return newRating;
+    }
+    
+    private void updateClip() {
+        final Rating control = getSkinnable();
+        final double h = control.getHeight() - (snappedTopInset() + snappedBottomInset());
+        final double w = control.getWidth() - (snappedLeftInset() + snappedRightInset());
+        
+        if (isVertical()) {
+        	final double y = h * rating / control.getMax() ;
+            forgroundClipRect.relocate(0, h - y);
+            forgroundClipRect.setWidth(control.getWidth());
+            forgroundClipRect.setHeight(y);
+        } else {
+        	final double x = w * rating / control.getMax();        	
+            forgroundClipRect.setWidth(x);
+            forgroundClipRect.setHeight(control.getHeight());
+        }
+    	
+    }
+    
+//    private double getSpacing() {
+//        return (backgroundContainer instanceof HBox) ?
+//                ((HBox)backgroundContainer).getSpacing() :
+//                ((VBox)backgroundContainer).getSpacing();
+//    }
+    
+    private Node createButton() {
+        Region btn = new Region();
+        btn.getStyleClass().add("button"); //$NON-NLS-1$
+        
+        btn.setOnMouseMoved(mouseMoveHandler);
+        btn.setOnMouseClicked(mouseClickHandler);
+        return btn;
+    }
+    
+    // Update the skin based on a new value for the rating.
+    // If we support partial ratings, updates the clip.
+    // Otherwise, updates the style classes for the buttons.
+    
+    private void updateRating() {
+    	
+    	double newRating = getSkinnable().getRating();
+    	    	
+        if (newRating == rating) return;
+        
+        rating = Utils.clamp(0, newRating, getSkinnable().getMax());
+
+        if (partialRating) {
+        	updateClip();
+        } else {
+            updateButtonStyles();
+        }
+    }
+
+	private void updateButtonStyles() {
+		final int max = getSkinnable().getMax();
+
+		// make a copy of the buttons list so that we can reverse the order if
+		// the list is vertical (as the buttons are ordered bottom to top).
+		List<Node> buttons = new ArrayList<>(backgroundContainer.getChildren());
+		if (isVertical()) {
+		    Collections.reverse(buttons);
+		}
+		
+		for (int i = 0; i < max; i++) {
+		    Node button = buttons.get(i);
+   
+		    final List<String> styleClass = button.getStyleClass();
+		    final boolean containsStrong = styleClass.contains(STRONG);
+		    
+		    if (i < rating) {
+		        if (! containsStrong) {
+		            styleClass.add(STRONG);
+		        }
+		    } else if (containsStrong) {
+		        styleClass.remove(STRONG);
+		    }
+		}
+	}
+    
+    private boolean isVertical() {
+        return getSkinnable().getOrientation() == Orientation.VERTICAL;
+    }
+    
+    @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return super.computePrefWidth(height, topInset, rightInset, bottomInset, leftInset);
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/SegmentedButtonSkin.java b/src/impl/org/controlsfx/skin/SegmentedButtonSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..ebb921ebcd9a0b7b230efdc59d09e888599f41cc
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/SegmentedButtonSkin.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import java.util.Collections;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.collections.ObservableList;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.control.ToggleGroup;
+import javafx.scene.layout.HBox;
+
+import org.controlsfx.control.SegmentedButton;
+
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+
+public class SegmentedButtonSkin extends BehaviorSkinBase<SegmentedButton, BehaviorBase<SegmentedButton>> {
+        
+    private static final String ONLY_BUTTON = "only-button"; //$NON-NLS-1$
+    private static final String LEFT_PILL   = "left-pill"; //$NON-NLS-1$
+    private static final String CENTER_PILL = "center-pill"; //$NON-NLS-1$
+    private static final String RIGHT_PILL  = "right-pill"; //$NON-NLS-1$
+
+    private final HBox container;
+
+    public SegmentedButtonSkin(SegmentedButton control) {
+        super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
+        
+        container = new HBox();
+        
+        getChildren().add(container);
+        
+        updateButtons();
+        getButtons().addListener(new InvalidationListener() {
+            @Override public void invalidated(Observable observable) {
+                updateButtons();
+            }
+        });
+        
+        control.toggleGroupProperty().addListener((observable, oldValue, newValue) -> {
+            getButtons().forEach((button) -> {
+                button.setToggleGroup(newValue);
+            });
+        });
+    }
+    
+    private ObservableList<ToggleButton> getButtons() {
+        return getSkinnable().getButtons();
+    }
+    
+    private void updateButtons() {
+        ObservableList<ToggleButton> buttons = getButtons();
+        ToggleGroup group = getSkinnable().getToggleGroup();
+        
+        container.getChildren().clear();
+        
+        for (int i = 0; i < getButtons().size(); i++) {
+            ToggleButton t = buttons.get(i);
+            
+            if (group != null) {
+                t.setToggleGroup(group);
+            }
+            
+            t.getStyleClass().removeAll(ONLY_BUTTON, LEFT_PILL, CENTER_PILL, RIGHT_PILL);
+            container.getChildren().add(t);
+
+            if (i == buttons.size() - 1) {
+                if (i == 0) {
+                    t.getStyleClass().add(ONLY_BUTTON);
+                } else {
+                    t.getStyleClass().add(RIGHT_PILL);
+                }
+            } else if (i == 0) {
+                t.getStyleClass().add(LEFT_PILL);
+            } else {
+                t.getStyleClass().add(CENTER_PILL);
+            }
+        }
+    }
+
+    @Override
+    protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return getSkinnable().prefWidth(height);
+    }
+
+    @Override
+    protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return getSkinnable().prefHeight(width);
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/SnapshotViewSkin.java b/src/impl/org/controlsfx/skin/SnapshotViewSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..5bdf23ef23ce73fc621a485f22740b26703b3aa2
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/SnapshotViewSkin.java
@@ -0,0 +1,566 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import impl.org.controlsfx.behavior.SnapshotViewBehavior;
+import javafx.beans.binding.Bindings;
+import javafx.beans.binding.BooleanBinding;
+import javafx.beans.property.ReadOnlyBooleanProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.geometry.Bounds;
+import javafx.geometry.Pos;
+import javafx.geometry.Rectangle2D;
+import javafx.scene.Cursor;
+import javafx.scene.Node;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.GridPane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.shape.StrokeType;
+
+import org.controlsfx.control.SnapshotView;
+import org.controlsfx.control.SnapshotView.Boundary;
+
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+
+/**
+ * View for the {@link SnapshotView}. It displays the node and the selection and manages their positioning. Mouse events
+ * are handed over to the {@link SnapshotViewBehavior} which uses them to change the selection.
+ */
+public class SnapshotViewSkin extends BehaviorSkinBase<SnapshotView, SnapshotViewBehavior> {
+
+    /* ************************************************************************
+     *                                                                         *
+     * Attributes & Properties                                                 *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * The currently displayed node; when the {@link SnapshotView#nodeProperty() node} property changes
+     * {@link #updateNode() updateNode} will set the new one.
+     */
+    private Node node;
+
+    /**
+     * The pane displaying the {@link #node}.
+     */
+    private final GridPane gridPane;
+
+    /**
+     * The (mutable) rectangle which represents the selected area.
+     */
+    private final Rectangle selectedArea;
+
+    /**
+     * The rectangle whose stroke represents the unselected area. Binding is used to ensure that the rectangle itself
+     * always has the same size and position as the {@link #selectedArea}.
+     */
+    private final Rectangle unselectedArea;
+
+    /**
+     * The node capturing mouse events.
+     */
+    private final Node mouseNode;
+
+    /* ************************************************************************
+     *                                                                         *
+     * Constructor & Initialization                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Creates a new skin for the specified {@link SnapshotView}.
+     * 
+     * @param snapshotView
+     *            the {@link SnapshotView} this skin will display
+     */
+    public SnapshotViewSkin(SnapshotView snapshotView) {
+
+        super(snapshotView, new SnapshotViewBehavior(snapshotView));
+
+        this.gridPane = createGridPane();
+        this.selectedArea = new Rectangle();
+        this.unselectedArea = new Rectangle();
+        this.mouseNode = createMouseNode();
+
+        buildSceneGraph();
+        initializeAreas();
+
+        registerChangeListener(snapshotView.nodeProperty(), "NODE"); //$NON-NLS-1$
+        registerChangeListener(snapshotView.selectionProperty(), "SELECTION"); //$NON-NLS-1$
+    }
+
+    @Override
+    protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+
+        if ("NODE".equals(p)) { //$NON-NLS-1$
+            updateNode();
+        } else if ("SELECTION".equals(p)) { //$NON-NLS-1$
+            updateSelection();
+        }
+    }
+
+    /**
+     * Creates the grid pane which will contain the node.
+     * 
+     * @return a {@link GridPane}
+     */
+    private static GridPane createGridPane() {
+        GridPane pane = new GridPane();
+        pane.setAlignment(Pos.CENTER);
+        return pane;
+    }
+
+    /**
+     * Creates the node which will be used to capture mouse events. Events are handed over to
+     * {@link #handleMouseEvent(MouseEvent) handleMouseEvent}.
+     * 
+     * @return a {@link Node}
+     */
+    private Node createMouseNode() {
+        Rectangle mouseNode = new Rectangle();
+
+        // make the node transparent and make sure its size does not affect the control's size
+        mouseNode.setFill(Color.TRANSPARENT);
+        mouseNode.setManaged(false);
+
+        // bind width and height to the control
+        mouseNode.widthProperty().bind(getSkinnable().widthProperty());
+        mouseNode.heightProperty().bind(getSkinnable().heightProperty());
+
+        // let it handle the mouse events if allowed by the user
+        mouseNode.addEventHandler(MouseEvent.ANY, this::handleMouseEvent);
+        mouseNode.mouseTransparentProperty().bind(getSkinnable().selectionMouseTransparentProperty());
+
+        return mouseNode;
+    }
+
+    /**
+     * Builds this skin's scene graph.
+     */
+    private void buildSceneGraph() {
+        getChildren().addAll(gridPane, unselectedArea, selectedArea, mouseNode);
+        updateNode();
+    }
+
+    /**
+     * Initializes the {@link #selectedArea} and the {@link #unselectedArea}. This includes their style and their
+     * bindings to the {@link SnapshotView#selectionProperty() selection} property.
+     */
+    private void initializeAreas() {
+        styleAreas();
+        bindAreaCoordinatesTogether();
+        bindAreaVisibilityToSelection();
+    }
+
+    /**
+     * Styles the selected and unselected area.
+     */
+    private void styleAreas() {
+        selectedArea.fillProperty().bind(getSkinnable().selectionAreaFillProperty());
+        selectedArea.strokeProperty().bind(getSkinnable().selectionBorderPaintProperty());
+        selectedArea.strokeWidthProperty().bind(getSkinnable().selectionBorderWidthProperty());
+        selectedArea.setStrokeType(StrokeType.OUTSIDE);
+        // if the control's layout depends on this rectangle,
+        // the stroke's width messes up the layout if the selection is on the pane's edge
+        selectedArea.setManaged(false);
+        selectedArea.setMouseTransparent(true);
+
+        unselectedArea.setFill(Color.TRANSPARENT);
+        unselectedArea.strokeProperty().bind(getSkinnable().unselectedAreaFillProperty());
+        unselectedArea.strokeWidthProperty().bind(
+                Bindings.max(getSkinnable().widthProperty(), getSkinnable().heightProperty()));
+        unselectedArea.setStrokeType(StrokeType.OUTSIDE);
+        // this call is crucial! it prevents the enormous unselected area from messing up the layout
+        unselectedArea.setManaged(false);
+        unselectedArea.setMouseTransparent(true);
+    }
+
+    /**
+     * Binds the position and size of {@link #unselectedArea} to {@link #selectedArea}.
+     */
+    private void bindAreaCoordinatesTogether() {
+        unselectedArea.xProperty().bind(selectedArea.xProperty());
+        unselectedArea.yProperty().bind(selectedArea.yProperty());
+        unselectedArea.widthProperty().bind(selectedArea.widthProperty());
+        unselectedArea.heightProperty().bind(selectedArea.heightProperty());
+    }
+
+    /**
+     * Binds the visibility of {@link #selectedArea} and {@link #unselectedArea} to the {@code SnapshotView} 's
+     * {@link SnapshotView#selectionActiveProperty() selectionActive} and {@link SnapshotView#hasSelectionProperty()
+     * selectionValid} properties.
+     */
+    @SuppressWarnings("unused")
+    private void bindAreaVisibilityToSelection() {
+        ReadOnlyBooleanProperty selectionExists = getSkinnable().hasSelectionProperty();
+        ReadOnlyBooleanProperty selectionActive = getSkinnable().selectionActiveProperty();
+        BooleanBinding existsAndActive = Bindings.and(selectionExists, selectionActive);
+
+        selectedArea.visibleProperty().bind(existsAndActive);
+        unselectedArea.visibleProperty().bind(existsAndActive);
+
+        // UGLY WORKAROUND AHEAD!
+        // The clipper should be created in 'styleAreas' but due to the problem explained in 'Clipper.setClip(Node)'
+        // it has to be created here where the visibility is determined.
+
+        // clip the unselected area according to the view's property - this is done by a designated inner class
+        new Clipper(getSkinnable(), unselectedArea, () -> unselectedArea.visibleProperty().bind(existsAndActive));
+    }
+
+    /* ************************************************************************
+     *                                                                         *
+     * Node                                                                    *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Displays the current {@link SnapshotView#nodeProperty() node}.
+     */
+    private void updateNode() {
+        if (node != null) {
+            gridPane.getChildren().remove(node);
+        }
+
+        node = getSkinnable().getNode();
+        if (node != null) {
+            gridPane.getChildren().add(0, node);
+        }
+    }
+
+    /* ************************************************************************
+     *                                                                         *
+     * Selection                                                               *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Updates the position and size of {@link #selectedArea} (and by binding that of {@link #unselectedArea}) to a
+     * changed selection.
+     */
+    private void updateSelection() {
+        boolean showSelection = getSkinnable().hasSelection() && getSkinnable().isSelectionActive();
+
+        if (showSelection) {
+            // the selection can be properly displayed
+            Rectangle2D selection = getSkinnable().getSelection();
+            setSelection(selection.getMinX(), selection.getMinY(), selection.getWidth(), selection.getHeight());
+        } else {
+            // in this case the selection areas are invisible,
+            // so the only thing left to do is to make sure their coordinates are not all over the place
+            // (this is not strictly necessary but makes the skin's state cleaner)
+            setSelection(0, 0, 0, 0);
+        }
+    }
+
+    /**
+     * Updates the position and size of {@link #selectedArea} (and by binding that of {@link #unselectedArea}) to the
+     * specified arguments.
+     * 
+     * @param x
+     *            the new x coordinate of the upper left corner
+     * @param y
+     *            the new y coordinate of the upper left corner
+     * @param width
+     *            the new width
+     * @param height
+     *            the new height
+     */
+    private void setSelection(double x, double y, double width, double height) {
+        selectedArea.setX(x);
+        selectedArea.setY(y);
+        selectedArea.setWidth(width);
+        selectedArea.setHeight(height);
+    }
+
+    /* ************************************************************************
+     *                                                                         *
+     * Mouse Events                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Handles mouse events.
+     * 
+     * @param event
+     *            the {@link MouseEvent} to handle
+     */
+    private void handleMouseEvent(MouseEvent event) {
+        Cursor newCursor = getBehavior().handleMouseEvent(event);
+        mouseNode.setCursor(newCursor);
+    }
+
+    /* ************************************************************************
+     *                                                                         *
+     * Inner Classes                                                           *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Clips the unselected area to the {@link SnapshotView#unselectedAreaBoundaryProperty() unselectedAreaBoundary}.
+     *
+     */
+    private static class Clipper {
+
+        /**
+         * The snapshot view to whose {@link Node#boundsInLocalProperty() boundsInLocal} the {@link #clippedNode} will
+         * be clipped.
+         */
+        private final SnapshotView snapshotView;
+
+        /**
+         * The node to which the clips will be added.
+         */
+        private final Node clippedNode;
+
+        /**
+         * A function which rebinds the clip's visibility after it was unbound. Only necessary because of the workaround
+         * explained in {@link #setClip(Node) setClip}.
+         */
+        private final Runnable rebindClippedNodeVisibility;
+
+        /**
+         * The {@link Rectangle} used to clip the {@link #clippedNode} to {@link Boundary#CONTROL}.
+         */
+        private final Rectangle controlClip;
+
+        /**
+         * The {@link Rectangle} used to clip the {@link #clippedNode} to {@link Boundary#NODE}.
+         */
+        private final Rectangle nodeClip;
+
+        /**
+         * A listener which updates the {@link #controlClip} when the {@link #snapshotView}'s
+         * {@link Node#boundsInLocalProperty() boundsInLocal} change.
+         */
+        private final ChangeListener<Bounds> updateControlClipToNewBoundsListener;
+
+        /**
+         * A listener which updates the {@link #nodeClip} when the {@link SnapshotView#nodeProperty() node}'s
+         * {@link Node#boundsInParentProperty() boundsInParent} change.
+         */
+        private final ChangeListener<Bounds> updateNodeClipToNewBoundsListener;
+
+        /**
+         * Creates a new clipper with the specified arguments.
+         * 
+         * @param snapshotView
+         *            the {@link SnapshotView} to whose bounds the {@code clippedNode} will be clipped
+         * @param clippedNode
+         *            the {@link Node} whose bounds will be clipped
+         * @param rebindClippedNodeVisibility
+         *            a function which rebinds the {@code clippedNode}'s visibility
+         */
+        public Clipper(SnapshotView snapshotView, Node clippedNode, Runnable rebindClippedNodeVisibility) {
+            this.snapshotView = snapshotView;
+            this.clippedNode = clippedNode;
+            this.rebindClippedNodeVisibility = rebindClippedNodeVisibility;
+
+            // for 'CONTROL', clip to the control's bounds
+            controlClip = new Rectangle();
+            updateControlClipToNewBoundsListener =
+                    (o, oldBounds, newBounds) -> resizeRectangleToBounds(controlClip, newBounds);
+
+            // for 'NODE', clip to the node's bounds
+            nodeClip = new Rectangle();
+            // create the listener which will resize the rectangle
+            updateNodeClipToNewBoundsListener =
+                    (o, oldBounds, newBounds) -> resizeRectangleToBounds(nodeClip, newBounds);
+
+            // set the clipping and keep updating it
+            setClipping();
+            snapshotView.unselectedAreaBoundaryProperty().addListener((o, oldBoundary, newBoundary) -> setClipping());
+        }
+
+        /**
+         * Sets clipping to the current {@link SnapshotView#unselectedAreaBoundaryProperty() unselectedAreaBoundary}.
+         */
+        private void setClipping() {
+            Boundary boundary = snapshotView.getUnselectedAreaBoundary();
+            switch (boundary) {
+            case CONTROL:
+                clipToControl();
+                break;
+            case NODE:
+                clipToNode();
+                break;
+            default:
+                throw new IllegalArgumentException("The boundary " + boundary + " is not fully implemented."); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+        }
+
+        /**
+         * Clips the {@link #clippedNode} to {@link #controlClip} and keeps updating the latter when the control changes
+         * its bounds.
+         */
+        private void clipToControl() {
+            // stop resizing the node clip
+            updateNodeClipToChangingNode(snapshotView.nodeProperty(), snapshotView.getNode(), null);
+
+            // resize the control clip and keep doing so
+            resizeRectangleToBounds(controlClip, snapshotView.getBoundsInLocal());
+            snapshotView.boundsInLocalProperty().addListener(updateControlClipToNewBoundsListener);
+
+            // set the clip
+            setClip(controlClip);
+        }
+
+        /**
+         * Clips the {@link #clippedNode} to {@link #nodeClip} and keeps updating the latter when the control changes
+         * its bounds.
+         */
+        private void clipToNode() {
+            // update the node clip to the new bounds and whenever the node changes its bounds
+            updateNodeClipToChangingNode(snapshotView.nodeProperty(), null, snapshotView.getNode());
+            // move that listener from old to new nodes
+            snapshotView.nodeProperty().addListener(this::updateNodeClipToChangingNode);
+
+            // set the clip
+            setClip(nodeClip);
+        }
+
+        /**
+         * Resizes the {@link #nodeClip} to the specified new node's {@link Node#boundsInParentProperty()
+         * boundsInParent} (or to an empty rectangle if it is {@code null}) and moves the
+         * {@link #updateNodeClipToNewBoundsListener} from the old to the new node's {@code boundInParents} property.
+         * <p>
+         * Designed to be used as a lambda method reference.
+         * 
+         * @param o
+         *            the {@link ObservableValue} which changed its value
+         * @param oldNode
+         *            the old node
+         * @param newNode
+         *            the new node
+         */
+        private void updateNodeClipToChangingNode(
+                @SuppressWarnings("unused") ObservableValue<? extends Node> o, Node oldNode, Node newNode) {
+
+            // resize the rectangle to match the new node
+            resizeRectangleToNodeBounds(nodeClip, newNode);
+
+            // move the listener from one node to the next
+            if (oldNode != null) {
+                oldNode.boundsInParentProperty().removeListener(updateNodeClipToNewBoundsListener);
+            }
+            if (newNode != null) {
+                newNode.boundsInParentProperty().addListener(updateNodeClipToNewBoundsListener);
+            }
+        }
+
+        /**
+         * Resizes the specified rectangle to the specified node's {@link Node#boundsInParentProperty() boundsInParent}.
+         * 
+         * @param rectangle
+         *            the {@link Rectangle} which will be resized
+         * @param node
+         *            the {@link Node} to whose bounds the {@code rectangle} will be resized
+         */
+        private static void resizeRectangleToNodeBounds(Rectangle rectangle, Node node) {
+            if (node == null) {
+                resizeRectangleToZero(rectangle);
+            } else {
+                resizeRectangleToBounds(rectangle, node.getBoundsInParent());
+            }
+        }
+
+        /**
+         * Resized the specified rectangle so that its upper left point is {@code (0, 0)} and its width and height are
+         * both 0.
+         * 
+         * @param rectangle
+         *            the {@link Rectangle} which will be resized
+         */
+        private static void resizeRectangleToZero(Rectangle rectangle) {
+            rectangle.setX(0);
+            rectangle.setY(0);
+            rectangle.setWidth(0);
+            rectangle.setHeight(0);
+        }
+
+        /**
+         * Resized the specified rectangle so that it matches the specified bounds, i.e. it will have the same upper
+         * left point and width and height.
+         * 
+         * @param rectangle
+         *            the {@link Rectangle} which will be resized
+         * @param bounds
+         *            the {@link Bounds} to which the rectangle will be resized
+         */
+        private static void resizeRectangleToBounds(Rectangle rectangle, Bounds bounds) {
+            rectangle.setX(bounds.getMinX());
+            rectangle.setY(bounds.getMinY());
+            rectangle.setWidth(bounds.getWidth());
+            rectangle.setHeight(bounds.getHeight());
+        }
+
+        /**
+         * Sets the specified clip on the {@link #clippedNode}.
+         * 
+         * @param clip
+         *            the {@link Node} which is used as a clip
+         */
+        private void setClip(Node clip) {
+
+            /*
+             * UGLY WORKAROUND
+             * 
+             * Setting the clip on the unselected area while it is invisible leads to either the clip having no effect
+             * or no area being displayed at all. Obviously I'm doing something wrong but I couldn't determine the root
+             * cause so I fixed the symptom. Now the area is turned visible, the clip is set and then it is made
+             * invisible again.
+             * 
+             * Everything below but 'clippedNode.setClip(clip);' is part of that workaround. To reproduce the bug
+             * comment all those lines out. Then, after 'HelloSnapshotView' started, select 'NODE' for the unselected
+             * area boundary and draw a selection on the node. The area above the node which is not selected should be
+             * painted in a semi-opaque black but due to the bug it is not. Instead the area outside of the selection
+             * has no paint at all and is simply transparent.
+             * Note that if the boundary is turned back to CONTROL, a selection is made and then NODE is set again, the
+             * clips works properly and the preexisting selection's outer area is clipped to the node.  
+             * 
+             * If someone finds out what the *$#&? I've been doing wrong, please fix and be so kind to mail to
+             * nipa@codefx.org! :)
+             */
+
+            boolean workAroundVisibilityProblem = !clippedNode.isVisible();
+            if (workAroundVisibilityProblem) {
+                clippedNode.visibleProperty().unbind();
+                clippedNode.setVisible(true);
+            }
+
+            clippedNode.setClip(clip);
+
+            if (workAroundVisibilityProblem) {
+                rebindClippedNodeVisibility.run();
+            }
+        }
+
+    }
+
+}
diff --git a/src/impl/org/controlsfx/skin/StatusBarSkin.java b/src/impl/org/controlsfx/skin/StatusBarSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..39a1b79e64f74634007b190566eadd52cd8782e7
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/StatusBarSkin.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import javafx.beans.Observable;
+import javafx.beans.binding.Bindings;
+import javafx.scene.control.Label;
+import javafx.scene.control.ProgressBar;
+import javafx.scene.control.SkinBase;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+
+import org.controlsfx.control.StatusBar;
+
+public class StatusBarSkin extends SkinBase<StatusBar> {
+    
+    private HBox leftBox;
+    private HBox rightBox;
+    private Label label;
+    private ProgressBar progressBar;
+
+    public StatusBarSkin(StatusBar statusBar) {
+        super(statusBar);
+
+        leftBox = new HBox();
+        leftBox.getStyleClass().add("left-items"); //$NON-NLS-1$
+
+        rightBox = new HBox();
+        rightBox.getStyleClass().add("right-items"); //$NON-NLS-1$
+
+        progressBar = new ProgressBar();
+        progressBar.progressProperty().bind(statusBar.progressProperty());
+        progressBar.visibleProperty().bind(
+                Bindings.notEqual(0, statusBar.progressProperty()));
+
+        label = new Label();
+        label.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
+        label.textProperty().bind(statusBar.textProperty());
+        label.graphicProperty().bind(statusBar.graphicProperty());
+        label.getStyleClass().add("status-label"); //$NON-NLS-1$
+
+        leftBox.getChildren().setAll(getSkinnable().getLeftItems());
+
+        rightBox.getChildren().setAll(getSkinnable().getRightItems());
+
+        statusBar.getLeftItems().addListener(
+                (Observable evt) -> leftBox.getChildren().setAll(
+                        getSkinnable().getLeftItems()));
+
+        statusBar.getRightItems().addListener(
+                (Observable evt) -> rightBox.getChildren().setAll(
+                        getSkinnable().getRightItems()));
+
+        GridPane gridPane = new GridPane();
+
+        GridPane.setFillHeight(leftBox, true);
+        GridPane.setFillHeight(rightBox, true);
+        GridPane.setFillHeight(label, true);
+        GridPane.setFillHeight(progressBar, true);
+
+        GridPane.setVgrow(leftBox, Priority.ALWAYS);
+        GridPane.setVgrow(rightBox, Priority.ALWAYS);
+        GridPane.setVgrow(label, Priority.ALWAYS);
+        GridPane.setVgrow(progressBar, Priority.ALWAYS);
+
+        GridPane.setHgrow(label, Priority.ALWAYS);
+
+        gridPane.add(leftBox, 0, 0);
+        gridPane.add(label, 1, 0);
+        gridPane.add(progressBar, 2, 0);
+        gridPane.add(rightBox, 4, 0);
+
+        getChildren().add(gridPane);
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/TaskProgressViewSkin.java b/src/impl/org/controlsfx/skin/TaskProgressViewSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e6fba60df633761923387ad9b3260b89c561886
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/TaskProgressViewSkin.java
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.skin;
+
+import javafx.beans.binding.Bindings;
+import javafx.concurrent.Task;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.ContentDisplay;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.control.ProgressBar;
+import javafx.scene.control.SkinBase;
+import javafx.scene.control.Tooltip;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.VBox;
+import javafx.util.Callback;
+
+import org.controlsfx.control.TaskProgressView;
+
+public class TaskProgressViewSkin<T extends Task<?>> extends
+        SkinBase<TaskProgressView<T>> {
+
+    public TaskProgressViewSkin(TaskProgressView<T> monitor) {
+        super(monitor);
+
+        BorderPane borderPane = new BorderPane();
+        borderPane.getStyleClass().add("box");
+
+        // list view
+        ListView<T> listView = new ListView<>();
+        listView.setPrefSize(500, 400);
+        listView.setPlaceholder(new Label("No tasks running"));
+        listView.setCellFactory(param -> new TaskCell());
+        listView.setFocusTraversable(false);
+
+        Bindings.bindContent(listView.getItems(), monitor.getTasks());
+        borderPane.setCenter(listView);
+
+        getChildren().add(listView);
+    }
+
+    class TaskCell extends ListCell<T> {
+        private ProgressBar progressBar;
+        private Label titleText;
+        private Label messageText;
+        private Button cancelButton;
+
+        private T task;
+        private BorderPane borderPane;
+
+        public TaskCell() {
+            titleText = new Label();
+            titleText.getStyleClass().add("task-title");
+
+            messageText = new Label();
+            messageText.getStyleClass().add("task-message");
+
+            progressBar = new ProgressBar();
+            progressBar.setMaxWidth(Double.MAX_VALUE);
+            progressBar.setMaxHeight(8);
+            progressBar.getStyleClass().add("task-progress-bar");
+
+            cancelButton = new Button("Cancel");
+            cancelButton.getStyleClass().add("task-cancel-button");
+            cancelButton.setTooltip(new Tooltip("Cancel Task"));
+            cancelButton.setOnAction(evt -> {
+                if (task != null) {
+                    task.cancel();
+                }
+            });
+
+            VBox vbox = new VBox();
+            vbox.setSpacing(4);
+            vbox.getChildren().add(titleText);
+            vbox.getChildren().add(progressBar);
+            vbox.getChildren().add(messageText);
+
+            BorderPane.setAlignment(cancelButton, Pos.CENTER);
+            BorderPane.setMargin(cancelButton, new Insets(0, 0, 0, 4));
+
+            borderPane = new BorderPane();
+            borderPane.setCenter(vbox);
+            borderPane.setRight(cancelButton);
+            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
+        }
+
+        @Override
+        public void updateIndex(int index) {
+            super.updateIndex(index);
+
+            /*
+             * I have no idea why this is necessary but it won't work without
+             * it. Shouldn't the updateItem method be enough?
+             */
+            if (index == -1) {
+                setGraphic(null);
+                getStyleClass().setAll("task-list-cell-empty");
+            }
+        }
+
+        @Override
+        protected void updateItem(T task, boolean empty) {
+            super.updateItem(task, empty);
+
+            this.task = task;
+
+            if (empty || task == null) {
+                getStyleClass().setAll("task-list-cell-empty");
+                setGraphic(null);
+            } else if (task != null) {
+                getStyleClass().setAll("task-list-cell");
+                progressBar.progressProperty().bind(task.progressProperty());
+                titleText.textProperty().bind(task.titleProperty());
+                messageText.textProperty().bind(task.messageProperty());
+                cancelButton.disableProperty().bind(
+                        Bindings.not(task.runningProperty()));
+
+                Callback<T, Node> factory = getSkinnable().getGraphicFactory();
+                if (factory != null) {
+                    Node graphic = factory.call(task);
+                    if (graphic != null) {
+                        BorderPane.setAlignment(graphic, Pos.CENTER);
+                        BorderPane.setMargin(graphic, new Insets(0, 4, 0, 0));
+                        borderPane.setLeft(graphic);
+                    }
+                } else {
+                	/*
+                	 * Really needed. The application might have used a graphic
+                	 * factory before and then disabled it. In this case the border
+                	 * pane might still have an old graphic in the left position.
+                	 */
+                	borderPane.setLeft(null);
+                }
+
+                setGraphic(borderPane);
+            }
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/skin/ToggleSwitchSkin.java b/src/impl/org/controlsfx/skin/ToggleSwitchSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..e752032425f68bd4b89a2cd821b8c128d7d101aa
--- /dev/null
+++ b/src/impl/org/controlsfx/skin/ToggleSwitchSkin.java
@@ -0,0 +1,242 @@
+/**
+ * Copyright (c) 2015, 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package impl.org.controlsfx.skin;
+
+import com.sun.javafx.css.converters.SizeConverter;
+import javafx.animation.TranslateTransition;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.value.WritableValue;
+import javafx.css.CssMetaData;
+import javafx.css.Styleable;
+import javafx.css.StyleableDoubleProperty;
+import javafx.css.StyleableProperty;
+import javafx.geometry.Pos;
+import javafx.scene.control.Label;
+import javafx.scene.control.SkinBase;
+import javafx.scene.layout.StackPane;
+import javafx.util.Duration;
+import org.controlsfx.control.ToggleSwitch;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Basic Skin implementation for the {@link ToggleSwitch}
+ */
+public class ToggleSwitchSkin extends SkinBase<ToggleSwitch>
+{
+    private final StackPane thumb;
+    private final StackPane thumbArea;
+    private final Label label;
+    private final StackPane labelContainer;
+    private final TranslateTransition transition;
+
+    /**
+     * Constructor for all ToggleSwitchSkin instances.
+     *
+     * @param control The ToggleSwitch for which this Skin should attach to.
+     */
+    public ToggleSwitchSkin(ToggleSwitch control) {
+        super(control);
+
+        thumb = new StackPane();
+        thumbArea = new StackPane();
+        label = new Label();
+        labelContainer = new StackPane();
+        transition = new TranslateTransition(Duration.millis(getThumbMoveAnimationTime()), thumb);
+
+        label.textProperty().bind(control.textProperty());
+        getChildren().addAll(labelContainer, thumbArea, thumb);
+        labelContainer.getChildren().addAll(label);
+        StackPane.setAlignment(label, Pos.CENTER_LEFT);
+
+        thumb.getStyleClass().setAll("thumb");
+        thumbArea.getStyleClass().setAll("thumb-area");
+
+        thumbArea.setOnMouseReleased(event -> mousePressedOnToggleSwitch(control));
+        thumb.setOnMouseReleased(event -> mousePressedOnToggleSwitch(control));
+        control.selectedProperty().addListener((observable, oldValue, newValue) -> {
+            if (newValue.booleanValue() != oldValue.booleanValue())
+                selectedStateChanged();
+        });
+    }
+
+    private void selectedStateChanged() {
+        if(transition != null){
+            transition.stop();
+        }
+        
+        double thumbAreaWidth = snapSize(thumbArea.prefWidth(-1));
+        double thumbWidth = snapSize(thumb.prefWidth(-1));
+        double distance = thumbAreaWidth - thumbWidth;
+        /**
+         * If we are not selected, we need to go from right to left.
+         */
+        if (!getSkinnable().isSelected()) {
+            thumb.setLayoutX(thumbArea.getLayoutX());
+            transition.setFromX(distance);
+            transition.setToX(0);
+        } else {
+            thumb.setTranslateX(thumbArea.getLayoutX());
+            transition.setFromX(0);
+            transition.setToX(distance);
+        }
+        transition.setCycleCount(1);
+        transition.play();
+    }
+
+    private void mousePressedOnToggleSwitch(ToggleSwitch toggleSwitch) {
+        toggleSwitch.setSelected(!toggleSwitch.isSelected());
+    }
+
+
+    /**
+     * How many milliseconds it should take for the thumb to go from
+     * one edge to the other
+     */
+    private DoubleProperty thumbMoveAnimationTime = null;
+
+    private DoubleProperty thumbMoveAnimationTimeProperty() {
+        if (thumbMoveAnimationTime == null) {
+            thumbMoveAnimationTime = new StyleableDoubleProperty(200) {
+
+                @Override
+                public Object getBean() {
+                    return ToggleSwitchSkin.this;
+                }
+
+                @Override
+                public String getName() {
+                    return "thumbMoveAnimationTime";
+                }
+
+                @Override
+                public CssMetaData<ToggleSwitch,Number> getCssMetaData() {
+                    return THUMB_MOVE_ANIMATION_TIME;
+                }
+           };
+        }
+        return thumbMoveAnimationTime;
+    }
+
+    private double getThumbMoveAnimationTime() {
+        return thumbMoveAnimationTime == null ? 200 : thumbMoveAnimationTime.get();
+    }
+
+    @Override
+    protected void layoutChildren(double contentX, double contentY, double contentWidth, double contentHeight) {
+        ToggleSwitch toggleSwitch = getSkinnable();
+        double thumbWidth = snapSize(thumb.prefWidth(-1));
+        double thumbHeight = snapSize(thumb.prefHeight(-1));
+        thumb.resize(thumbWidth, thumbHeight);
+        //We must reset the TranslateX otherwise the thumb is mis-aligned when window is resized.
+         if (transition != null) {
+            transition.stop();
+        }
+        thumb.setTranslateX(0);
+
+        double thumbAreaY = snapPosition(contentY);
+        double thumbAreaWidth = snapSize(thumbArea.prefWidth(-1));
+        double thumbAreaHeight = snapSize(thumbArea.prefHeight(-1));
+
+        thumbArea.resize(thumbAreaWidth, thumbAreaHeight);
+        thumbArea.setLayoutX(contentWidth - thumbAreaWidth);
+        thumbArea.setLayoutY(thumbAreaY);
+
+        labelContainer.resize(contentWidth - thumbAreaWidth, thumbAreaHeight);
+        labelContainer.setLayoutY(thumbAreaY);
+
+        if (!toggleSwitch.isSelected())
+            thumb.setLayoutX(thumbArea.getLayoutX());
+        else
+            thumb.setLayoutX(thumbArea.getLayoutX() + thumbAreaWidth - thumbWidth);
+        thumb.setLayoutY(thumbAreaY + (thumbAreaHeight - thumbHeight) / 2);
+    }
+
+
+    @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return leftInset + label.prefWidth(-1) + thumbArea.prefWidth(-1) + rightInset;
+    }
+
+    @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return topInset + Math.max(thumb.prefHeight(-1), label.prefHeight(-1)) + bottomInset;
+    }
+
+    @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return leftInset + label.prefWidth(-1) + 20 + thumbArea.prefWidth(-1) + rightInset;
+    }
+
+    @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return topInset + Math.max(thumb.prefHeight(-1), label.prefHeight(-1)) + bottomInset;
+    }
+
+    private static final CssMetaData<ToggleSwitch, Number> THUMB_MOVE_ANIMATION_TIME =
+            new CssMetaData<ToggleSwitch, Number>("-thumb-move-animation-time",
+                    SizeConverter.getInstance(), 200) {
+
+                @Override
+                public boolean isSettable(ToggleSwitch toggleSwitch) {
+                    final ToggleSwitchSkin skin = (ToggleSwitchSkin) toggleSwitch.getSkin();
+                    return skin.thumbMoveAnimationTime == null ||
+                            !skin.thumbMoveAnimationTime.isBound();
+                }
+
+                @Override
+                public StyleableProperty<Number> getStyleableProperty(ToggleSwitch toggleSwitch) {
+                    final ToggleSwitchSkin skin = (ToggleSwitchSkin) toggleSwitch.getSkin();
+                    return (StyleableProperty<Number>) (WritableValue<Number>) skin.thumbMoveAnimationTimeProperty();
+                }
+            };
+
+    private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
+
+    static {
+        final List<CssMetaData<? extends Styleable, ?>> styleables =
+                new ArrayList<CssMetaData<? extends Styleable, ?>>(SkinBase.getClassCssMetaData());
+        styleables.add(THUMB_MOVE_ANIMATION_TIME);
+        STYLEABLES = Collections.unmodifiableList(styleables);
+    }
+
+    /**
+     * @return The CssMetaData associated with this class, which may include the
+     * CssMetaData of its super classes.
+     */
+    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
+        return STYLEABLES;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
+        return getClassCssMetaData();
+    }
+}
+
diff --git a/src/impl/org/controlsfx/spreadsheet/CellView.java b/src/impl/org/controlsfx/spreadsheet/CellView.java
new file mode 100644
index 0000000000000000000000000000000000000000..591e1eba51bdbf92e7bbb801de568b78fdb63fba
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/CellView.java
@@ -0,0 +1,659 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.logging.Logger;
+import javafx.animation.FadeTransition;
+import javafx.application.Platform;
+import javafx.beans.binding.When;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.beans.value.WeakChangeListener;
+import javafx.collections.ObservableList;
+import javafx.collections.SetChangeListener;
+import javafx.collections.WeakSetChangeListener;
+import javafx.event.EventHandler;
+import javafx.event.WeakEventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.ContentDisplay;
+import javafx.scene.control.Control;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TablePositionBase;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TableView.TableViewFocusModel;
+import javafx.scene.control.TableView.TableViewSelectionModel;
+import javafx.scene.control.Tooltip;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.DragEvent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.input.TransferMode;
+import javafx.scene.layout.Region;
+import javafx.util.Duration;
+import org.controlsfx.control.spreadsheet.Grid;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetCellEditor;
+import org.controlsfx.control.spreadsheet.SpreadsheetCellType;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+/**
+ * 
+ * The View cell that will be visible on screen. It holds the
+ * {@link SpreadsheetCell}.
+ */
+public class CellView extends TableCell<ObservableList<SpreadsheetCell>, SpreadsheetCell> {
+    private final SpreadsheetHandle handle;
+    /**
+     * Because we don't want to recreate Tooltip each time the TableCell is
+     * re-used. We save it properly here so we avoid recreating it each time
+     * since it's really time-consuming.
+     */
+    private Tooltip tooltip;
+
+    /***************************************************************************
+     * * Static Fields * *
+     **************************************************************************/
+    private static final String ANCHOR_PROPERTY_KEY = "table.anchor"; //$NON-NLS-1$
+    private static final int TOOLTIP_MAX_WIDTH = 400;
+    private static final Duration FADE_DURATION = Duration.millis(200);
+
+    static TablePositionBase<?> getAnchor(Control table, TablePositionBase<?> focusedCell) {
+        return hasAnchor(table) ? (TablePositionBase<?>) table.getProperties().get(ANCHOR_PROPERTY_KEY) : focusedCell;
+    }
+
+    static boolean hasAnchor(Control table) {
+        return table.getProperties().get(ANCHOR_PROPERTY_KEY) != null;
+    }
+
+    static void setAnchor(Control table, TablePositionBase anchor) {
+        if (table != null && anchor == null) {
+            removeAnchor(table);
+        } else {
+            table.getProperties().put(ANCHOR_PROPERTY_KEY, anchor);
+        }
+    }
+    
+    static void removeAnchor(Control table) {
+        table.getProperties().remove(ANCHOR_PROPERTY_KEY);
+    }
+    /***************************************************************************
+     * * Constructor * *
+     **************************************************************************/
+    public CellView(SpreadsheetHandle handle) {
+        this.handle = handle;
+        // When we detect a drag, we start the Full Drag so that other event
+        // will be fired
+        this.addEventHandler(MouseEvent.DRAG_DETECTED, new WeakEventHandler<>(startFullDragEventHandler));
+        setOnMouseDragEntered(new WeakEventHandler<>(dragMouseEventHandler));
+        
+        itemProperty().addListener(itemChangeListener);
+        
+    	setOnMousePressed(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {
+				getTableView().fireEvent(event);
+			}
+    	});
+    
+    }
+
+    /***************************************************************************
+     * * Public Methods * *
+     **************************************************************************/
+    @Override
+    public void startEdit() {
+        if (!isEditable()) {
+            getTableView().edit(-1, null);
+            return;
+        } 
+        /**
+         * If this CellView has no parent, this means that it was stacked into
+         * the cellsMap of the GridRowSkin, but the weakRef was dropped. So this
+         * CellView is still reacting to events, but it's not part of the
+         * sceneGraph! So we must deactivate this cell and let the real Cell in
+         * the sceneGraph take the edition.
+         */
+        if(getParent() == null){
+            updateTableView(null);
+            updateTableRow(null);
+            updateTableColumn(null);
+            return;
+        }
+        final int column = this.getTableView().getColumns().indexOf(this.getTableColumn());
+        final int row = getIndex();
+        // We start to edit only if the Cell is a normal Cell (aka visible).
+        final SpreadsheetView spv = handle.getView();
+        final Grid grid = spv.getGrid();
+        final SpreadsheetView.SpanType type = grid.getSpanType(spv, row, column);
+        //FIXME with the reverse algorithm in virtualFlow, is this still necessary?
+        if (type == SpreadsheetView.SpanType.NORMAL_CELL || type == SpreadsheetView.SpanType.ROW_VISIBLE) {
+
+            /**
+             * We may come to the situation where this method is called two
+             * times. One time by the row inside the VirtualFlow. And another by
+             * the row inside myFixedCells used by our GridVirtualFlow.
+             * 
+             * In that case, we have to give priority to the one used by the
+             * VirtualFlow. So we just check if the row is managed. If not, we
+             * know for sure that the our GridVirtualFlow has stepped out.
+             */
+            if (!getTableRow().isManaged()) {
+                return;
+            }
+
+            GridCellEditor editor = getEditor(getItem(), spv);
+            if (editor != null) {
+                super.startEdit();
+                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
+                editor.startEdit();
+            }else{
+                getTableView().edit(-1, null);
+            }
+        }
+    }
+
+    @Override
+    public void commitEdit(SpreadsheetCell newValue) {
+        //When commiting, we bring the value smoothly.
+        FadeTransition fadeTransition = new FadeTransition(FADE_DURATION, this);
+        fadeTransition.setFromValue(0);
+        fadeTransition.setToValue(1);
+        fadeTransition.play();
+        
+        if (!isEditing()) {
+            return;
+        }
+        super.commitEdit(newValue);
+
+        setContentDisplay(ContentDisplay.LEFT);
+        updateItem(newValue, false);
+
+        if (getTableView() != null) {
+            getTableView().requestFocus();
+        }
+    }
+
+    @Override
+    public void cancelEdit() {
+        if (!isEditing()) {
+            return;
+        }
+
+        super.cancelEdit();
+
+        setContentDisplay(ContentDisplay.LEFT);
+        updateItem(getItem(), false);
+
+        if (getTableView() != null) {
+            getTableView().requestFocus();
+        }
+    }
+
+    @Override
+    public void updateItem(final SpreadsheetCell item, boolean empty) {
+        final boolean emptyRow = getTableView().getItems().size() < getIndex() + 1;
+        /**
+         * don't call super.updateItem() because it will trigger cancelEdit() if
+         * the cell is being edited. It causes calling commitEdit() ALWAYS call
+         * cancelEdit as well which is undesired.
+         * 
+         */
+        if (!isEditing()) {
+            super.updateItem(item, empty && emptyRow);
+        }
+        if (empty && isSelected()) {
+            updateSelected(false);
+        }
+        if (empty && emptyRow) {
+            textProperty().unbind();
+            setText(null);
+            // do not nullify graphic here. Let the TableRow to control cell
+            // dislay
+            // setGraphic(null);
+            setContentDisplay(null);
+        } else if (!isEditing() && item != null) {
+            show(item);
+            if (item.getGraphic() == null) {
+                setGraphic(null);
+            }
+        }
+    }
+
+    /**
+     * Called in the gridRowSkinBase when doing layout This allow not to
+     * override opacity in the row and let the cell handle itself
+     * @param cell
+     */
+    public void show(final SpreadsheetCell cell) {
+        // We reset the settings
+        textProperty().bind(cell.textProperty());
+        setCellGraphic(cell);
+
+        Optional<String> tooltipText = cell.getTooltip();
+        String trimTooltip = tooltipText.isPresent() ? tooltipText.get().trim() : null;
+        
+        if (trimTooltip != null && !trimTooltip.isEmpty()) {
+            /**
+             * Here we check if the Tooltip has not been created in order NOT TO
+             * re-create it for nothing as it is a really time-consuming
+             * operation.
+             */
+            Tooltip localTooltip = getAvailableTooltip();
+            if (localTooltip != null) {
+                if (!Objects.equals(localTooltip.getText(), trimTooltip)) {
+                    getTooltip().setText(trimTooltip);
+                }
+            } else {
+                /**
+                 * Ensure that modification of ToolTip are set on the JFX thread
+                 * because an exception can be thrown otherwise.
+                 */
+                getValue(() -> {
+                    Tooltip newTooltip = new Tooltip(tooltipText.get());
+                    newTooltip.setWrapText(true);
+                    newTooltip.setMaxWidth(TOOLTIP_MAX_WIDTH);
+                    setTooltip(newTooltip);
+                }
+                );
+            }
+        } else {
+            //We save that tooltip
+            if(getTooltip() != null){
+                tooltip = getTooltip();
+            }
+            setTooltip(null);
+        }
+        
+        setWrapText(cell.isWrapText());
+
+        setEditable(cell.isEditable());
+        
+        if (cell.getCellType().acceptDrop()) {
+            setOnDragOver(new EventHandler<DragEvent>() {
+
+                @Override
+                public void handle(DragEvent event) {
+                    Dragboard db = event.getDragboard();
+                    if (db.hasFiles()) {
+                        event.acceptTransferModes(TransferMode.ANY);
+                    } else {
+                        event.consume();
+                    }
+                }
+            });
+            // Dropping over surface
+            setOnDragDropped(new EventHandler<DragEvent>() {
+                @Override
+                public void handle(DragEvent event) {
+                    Dragboard db = event.getDragboard();
+                    boolean success = false;
+                    if (db.hasFiles() && db.getFiles().size() == 1) {
+                        if (getItem().getCellType().match(db.getFiles().get(0))) {
+                            handle.getView().getGrid().setCellValue(getItem().getRow(), getItem().getColumn(),
+                                    getItem().getCellType().convertValue(db.getFiles().get(0)));
+                            success = true;
+                        }
+                    }
+                    event.setDropCompleted(success);
+                    event.consume();
+                }
+            });
+        } else {
+            setOnDragOver(null);
+            setOnDragDropped(null);
+        }
+    }
+
+    /***************************************************************************
+     * * Private Methods * *
+     **************************************************************************/
+
+    /**
+     * See if a tootlip is available (either on the TableCell already, or in the
+     * Stack). And then set it to the TableCell.
+     *
+     * @return
+     */
+    private Tooltip getAvailableTooltip(){
+        if(getTooltip() != null){
+            return getTooltip();
+        }
+        if(tooltip != null){
+            setTooltip(tooltip);
+            return tooltip;
+        }
+        return null;
+    }
+    
+    private void setCellGraphic(SpreadsheetCell item) {
+
+        if (isEditing()) {
+            return;
+        }
+        Node graphic = item.getGraphic();
+        if (graphic != null) {
+            /**
+             * This workaround is added for the first row containing a graphic
+             * because for an unknown reason, the graphic is translated to a
+             * negative value so it's not fully visible. So we add those
+             * listener that watch those changes, and try to get the previous
+             * value (the right one) if the new value goes out of bounds.
+             */
+//            if (item.getRow() == 0) {
+//                graphic.layoutXProperty().removeListener(firstRowLayoutXListener);
+//                graphic.layoutXProperty().addListener(firstRowLayoutXListener);
+//
+//                graphic.layoutYProperty().removeListener(firstRowLayoutYListener);
+//                graphic.layoutYProperty().addListener(firstRowLayoutYListener);
+//            }
+            
+            if (graphic instanceof ImageView) {
+                ImageView image = (ImageView) graphic;
+                image.setCache(true);
+                image.setPreserveRatio(true);
+                image.setSmooth(true);
+                if(image.getImage() != null){
+                image.fitHeightProperty().bind(
+                        new When(heightProperty().greaterThan(image.getImage().getHeight())).then(
+                                image.getImage().getHeight()).otherwise(heightProperty()));
+                image.fitWidthProperty().bind(
+                        new When(widthProperty().greaterThan(image.getImage().getWidth())).then(
+                                image.getImage().getWidth()).otherwise(widthProperty()));
+                }
+                /**
+                 * If we have a Region and no text, we force it to take full
+                 * space. But we want to impact the minSize in order to let the
+                 * prefSize to be computed if necessary.
+                 */
+            } else if (graphic instanceof Region && item.getItem() == null) {
+                Region region = (Region) graphic;
+                region.minHeightProperty().bind(heightProperty());
+                region.minWidthProperty().bind(widthProperty());
+            }
+            setGraphic(graphic);
+            /**
+             * In case of a resize of the column, we have new cells that steal
+             * the image from the original TableCell. So we check here if we are
+             * not in that case so that the Graphic of the SpreadsheetCell will
+             * always be on the latest tableView and therefore fully visible.
+             */
+            if (!getChildren().contains(graphic)) {
+                getChildren().add(graphic);
+            }
+        } else {
+            setGraphic(null);
+        }
+    }
+
+//    private final ChangeListener<Number> firstRowLayoutXListener = new ChangeListener<Number>() {
+//        @Override
+//        public void changed(ObservableValue<? extends Number> ov, Number oldLayoutX, Number newLayoutX) {
+//            if (getItem() != null && getItem().getGraphic() != null && newLayoutX.doubleValue() < 0 && oldLayoutX != null) {
+//                getItem().getGraphic().setLayoutX(oldLayoutX.doubleValue());
+//            }
+//        }
+//    };
+//    
+//    private final ChangeListener<Number> firstRowLayoutYListener = new ChangeListener<Number>() {
+//        @Override
+//        public void changed(ObservableValue<? extends Number> ov, Number oldLayoutY, Number newLayoutY) {
+//            if (getItem() != null && getItem().getGraphic() != null && newLayoutY.doubleValue() < 0 && oldLayoutY != null) {
+//                getItem().getGraphic().setLayoutY(oldLayoutY.doubleValue());
+//            }
+//        }
+//    };
+    
+    /**
+     * Return an instance of Editor specific to the Cell type We are not using
+     * the build-in editor-Cell because we cannot know in advance which editor
+     * we will need. Furthermore, we want to control the behavior very closely
+     * in regards of the spanned cell (invisible etc).
+     * 
+     * @param cell
+     *            The SpreadsheetCell
+     * @param bc
+     *            The SpreadsheetCell
+     * @return
+     */
+    private GridCellEditor getEditor(final SpreadsheetCell cell, final SpreadsheetView spv) {
+        SpreadsheetCellType<?> cellType = cell.getCellType();
+        Optional<SpreadsheetCellEditor> cellEditor = spv.getEditor(cellType);
+
+        if (cellEditor.isPresent()) {
+            GridCellEditor editor = handle.getCellsViewSkin().getSpreadsheetCellEditorImpl();
+            /**
+             * Sometimes, we end up here with the editor already editing. But
+             * this case should not happen. If a cell is calling startEdit,
+             * this means we want to edit the cell and the editor should not be
+             * editing another cell. So we just cancel the edition and give the
+             * editor to the cell because we may not be able to edit anything.
+             */
+            if (editor.isEditing()) {
+                if (editor.getModelCell() != null) {
+                    StringBuilder builder = new StringBuilder();
+                    builder.append("The cell at row ").append(editor.getModelCell().getRow())
+                            .append(" and column ").append(editor.getModelCell().getColumn())
+                            .append(" was in edition and cell at row ").append(cell.getRow())
+                            .append(" and column ").append(cell.getColumn())
+                            .append(" requested edition. This situation should not happen as the previous cell should not be in edition.");
+                    Logger.getLogger("root").warning(builder.toString());
+                }
+
+                editor.endEdit(false);
+            }
+            
+            editor.updateSpreadsheetCell(this);
+            editor.updateDataCell(cell);
+            editor.updateSpreadsheetCellEditor(cellEditor.get());
+            return editor;
+        } else {
+            return null;
+        }
+    }
+
+    private final ChangeListener<Node> graphicListener = new ChangeListener<Node>() {
+        @Override
+        public void changed(ObservableValue<? extends Node> arg0, Node arg1, Node newGraphic) {
+            setCellGraphic(getItem());
+        }
+    };
+
+    private final WeakChangeListener<Node> weakGraphicListener = new WeakChangeListener<>(graphicListener);
+    
+    private final SetChangeListener<String> styleClassListener = new SetChangeListener<String>() {
+        @Override
+        public void onChanged(javafx.collections.SetChangeListener.Change<? extends String> arg0) {
+            if (arg0.wasAdded()) {
+                getStyleClass().add(arg0.getElementAdded());
+            } else if (arg0.wasRemoved()) {
+                getStyleClass().remove(arg0.getElementRemoved());
+            }
+        }
+    };
+    
+    private final WeakSetChangeListener<String> weakStyleClassListener = new WeakSetChangeListener<>(styleClassListener);
+    
+    //Listeners for the styles, not initialized by default in order not to impact performance
+    private ChangeListener<String> styleListener;
+    private WeakChangeListener<String> weakStyleListener;
+    
+    /**
+     * Method that will select all the cells between the drag place and that
+     * cell.
+     * 
+     * @param e
+     */
+    private void dragSelect(MouseEvent e) {
+        // If the mouse event is not contained within this tableCell, then
+        // we don't want to react to it.
+        if (!this.contains(e.getX(), e.getY())) {
+            return;
+        }
+        final TableView<ObservableList<SpreadsheetCell>> tableView = getTableView();
+        if (tableView == null) {
+            return;
+        }
+
+        final int count = tableView.getItems().size();
+        if (getIndex() >= count) {
+            return;
+        }
+
+        final TableViewSelectionModel<ObservableList<SpreadsheetCell>> sm = tableView.getSelectionModel();
+        if (sm == null) {
+            return;
+        }
+
+        final int row = getIndex();
+        final int column = tableView.getVisibleLeafIndex(getTableColumn());
+
+        // For spanned Cells
+        final SpreadsheetCell cell = (SpreadsheetCell) getItem();
+        final int rowCell = cell.getRow() + cell.getRowSpan() - 1;
+        final int columnCell = cell.getColumn() + cell.getColumnSpan() - 1;
+
+        final TableViewFocusModel<?> fm = tableView.getFocusModel();
+        if (fm == null) {
+            return;
+        }
+
+        final TablePositionBase<?> focusedCell = fm.getFocusedCell();
+        final MouseButton button = e.getButton();
+        if (button == MouseButton.PRIMARY) {
+            // we add all cells/rows between the current selection focus and
+            // this cell/row (inclusive) to the current selection.
+            final TablePositionBase<?> anchor = getAnchor(tableView, focusedCell);
+
+            /**
+             * FIXME We need to clarify how we want to select the cells. If a
+             * spanned cell is in the way, which minRow/maxRow will be taken?
+             * Where the mouse is exactly? Or where the "motherCell" is? This
+             * needs some thinking.
+             */
+            // and then determine all row and columns which must be selected
+            int minRow = Math.min(anchor.getRow(), row);
+            minRow = Math.min(minRow, rowCell);
+            int maxRow = Math.max(anchor.getRow(), row);
+            maxRow = Math.max(maxRow, rowCell);
+            int minColumn = Math.min(anchor.getColumn(), column);
+            minColumn = Math.min(minColumn, columnCell);
+            int maxColumn = Math.max(anchor.getColumn(), column);
+            maxColumn = Math.max(maxColumn, columnCell);
+
+            // clear selection, but maintain the anchor
+            if (!e.isShortcutDown())
+                sm.clearSelection();
+            if (minColumn != -1 && maxColumn != -1)
+                sm.selectRange(minRow, tableView.getColumns().get(minColumn), maxRow,
+                        tableView.getColumns().get(maxColumn));
+            setAnchor(tableView, anchor);
+        }
+
+    }
+
+    /**
+     * Will safely execute the request on the JFX thread by checking whether we
+     * are on the JFX thread or not.
+     * 
+     * @param runnable
+     */
+    public static void getValue(final Runnable runnable) {
+        if (Platform.isFxApplicationThread()) {
+            runnable.run();
+        } else {
+            Platform.runLater(runnable);
+        }
+    }
+
+    @Override
+    protected javafx.scene.control.Skin<?> createDefaultSkin() {
+        return new CellViewSkin(this);
+    };
+    
+    private final EventHandler<MouseEvent> startFullDragEventHandler = new EventHandler<MouseEvent>() {
+        @Override
+        public void handle(MouseEvent arg0) {
+            if (handle.getGridView().getSelectionModel().getSelectionMode().equals(SelectionMode.MULTIPLE)) {
+                setAnchor(getTableView(), getTableView().getFocusModel().getFocusedCell());
+                startFullDrag();
+            }
+        }
+    };
+    
+    private final EventHandler<MouseEvent> dragMouseEventHandler = new EventHandler<MouseEvent>() {
+        @Override
+        public void handle(MouseEvent arg0) {
+            dragSelect(arg0);
+        }
+    };
+    
+    private final ChangeListener<SpreadsheetCell> itemChangeListener = new ChangeListener<SpreadsheetCell>() {
+
+        @Override
+        public void changed(ObservableValue<? extends SpreadsheetCell> arg0, SpreadsheetCell oldItem,
+                SpreadsheetCell newItem) {
+            if (oldItem != null) {
+                oldItem.getStyleClass().removeListener(weakStyleClassListener);
+                oldItem.graphicProperty().removeListener(weakGraphicListener);
+                
+                if(oldItem.styleProperty() != null){
+                    oldItem.styleProperty().removeListener(weakStyleListener);
+                }
+            }
+            if (newItem != null) {
+         getStyleClass().clear();
+                getStyleClass().setAll(newItem.getStyleClass());
+
+                newItem.getStyleClass().addListener(weakStyleClassListener);
+                setCellGraphic(newItem);
+                newItem.graphicProperty().addListener(weakGraphicListener);
+                
+                if(newItem.styleProperty() != null){
+                    initStyleListener();
+                    newItem.styleProperty().addListener(weakStyleListener);
+                    setStyle(newItem.getStyle());
+                }else{
+                    //We clear the previous style.
+                    setStyle(null);
+                }
+    }
+        }
+    };
+    
+    private void initStyleListener(){
+        if(styleListener == null){
+            styleListener = (ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
+                styleProperty().set(newValue);
+            };
+        }
+        weakStyleListener = new WeakChangeListener<>(styleListener);
+    }
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/CellViewSkin.java b/src/impl/org/controlsfx/spreadsheet/CellViewSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..a41ff3df307e27eb680d743cccadf1d446f86ff1
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/CellViewSkin.java
@@ -0,0 +1,224 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import com.sun.javafx.scene.control.skin.TableCellSkin;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.beans.value.WeakChangeListener;
+import javafx.collections.ObservableList;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.event.WeakEventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.TableCell;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.Region;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell.CornerPosition;
+
+/**
+ *
+ * This is the skin for the {@link CellView}.
+ *
+ * Its main goal is to draw an object (a triangle) on cells which have their
+ * {@link SpreadsheetCell#commentedProperty()} set to true.
+ *
+ */
+public class CellViewSkin extends TableCellSkin<ObservableList<SpreadsheetCell>, SpreadsheetCell> {
+
+    private final static String TOP_LEFT_CLASS = "top-left"; //$NON-NLS-1$
+    private final static String TOP_RIGHT_CLASS = "top-right"; //$NON-NLS-1$
+    private final static String BOTTOM_RIGHT_CLASS = "bottom-right"; //$NON-NLS-1$
+    private final static String BOTTOM_LEFT_CLASS = "bottom-left"; //$NON-NLS-1$
+    /**
+     * The size of the edge of the triangle FIXME Handling of static variable
+     * will be changed.
+     */
+    private static final int TRIANGLE_SIZE = 8;
+    /**
+     * The region we will add on the cell when necessary.
+     */
+    private Region topLeftRegion = null;
+    private Region topRightRegion = null;
+    private Region bottomRightRegion = null;
+    private Region bottomLeftRegion = null;
+
+    public CellViewSkin(TableCell<ObservableList<SpreadsheetCell>, SpreadsheetCell> tableCell) {
+        super(tableCell);
+        tableCell.itemProperty().addListener(weakItemChangeListener);
+        if (tableCell.getItem() != null) {
+            tableCell.getItem().addEventHandler(SpreadsheetCell.CORNER_EVENT_TYPE, weakTriangleEventHandler);
+        }
+    }
+
+    @Override
+    protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        /**
+         * If we have an Image in the Cell, its fitHeight will be affected by
+         * the cell height (see CellView). But during calculation for autofit
+         * option, we want to know the real prefHeight of this cell. Apparently,
+         * the fitHeight option is returned by default so we must override and
+         * return the Height of the image inside.
+         */
+        Node graphic = getSkinnable().getGraphic();
+        if (graphic != null && graphic instanceof ImageView) {
+            ImageView view = (ImageView) graphic;
+            if (view.getImage() != null) {
+                return view.getImage().getHeight();
+            }
+        }
+        return super.computePrefHeight(width, topInset, rightInset, bottomInset, leftInset);
+    }
+    
+    @Override
+    protected void layoutChildren(double x, final double y, final double w, final double h) {
+        super.layoutChildren(x, y, w, h);
+        if (getSkinnable().getItem() != null) {
+            layoutTriangle();
+        }
+    }
+
+    private void layoutTriangle() {
+        SpreadsheetCell cell = getSkinnable().getItem();
+        
+        handleTopLeft(cell);
+        handleTopRight(cell);
+        handleBottomLeft(cell);
+        handleBottomRight(cell);
+
+        getSkinnable().requestLayout();
+    }
+
+    private void handleTopLeft(SpreadsheetCell cell) {
+        if (cell.isCornerActivated(CornerPosition.TOP_LEFT)) {
+            if (topLeftRegion == null) {
+                topLeftRegion = getRegion(CornerPosition.TOP_LEFT);
+            }
+            if (!getChildren().contains(topLeftRegion)) {
+                getChildren().add(topLeftRegion);
+            }
+            topLeftRegion.relocate(0, snappedTopInset() - 1);
+        } else if (topLeftRegion != null) {
+            getChildren().remove(topLeftRegion);
+            topLeftRegion = null;
+        }
+    }
+
+    private void handleTopRight(SpreadsheetCell cell) {
+        if (cell.isCornerActivated(CornerPosition.TOP_RIGHT)) {
+            if (topRightRegion == null) {
+                topRightRegion = getRegion(CornerPosition.TOP_RIGHT);
+            }
+            if (!getChildren().contains(topRightRegion)) {
+                getChildren().add(topRightRegion);
+            }
+            topRightRegion.relocate(getSkinnable().getWidth() - TRIANGLE_SIZE, snappedTopInset() - 1);
+        } else if (topRightRegion != null) {
+            getChildren().remove(topRightRegion);
+            topRightRegion = null;
+        }
+    }
+
+    private void handleBottomRight(SpreadsheetCell cell) {
+        if (cell.isCornerActivated(CornerPosition.BOTTOM_RIGHT)) {
+            if (bottomRightRegion == null) {
+                bottomRightRegion = getRegion(CornerPosition.BOTTOM_RIGHT);
+            }
+            if (!getChildren().contains(bottomRightRegion)) {
+                getChildren().add(bottomRightRegion);
+            }
+            bottomRightRegion.relocate(getSkinnable().getWidth() - TRIANGLE_SIZE, getSkinnable().getHeight() - TRIANGLE_SIZE);
+        } else if (bottomRightRegion != null) {
+            getChildren().remove(bottomRightRegion);
+            bottomRightRegion = null;
+        }
+    }
+    private void handleBottomLeft(SpreadsheetCell cell) {
+        if (cell.isCornerActivated(CornerPosition.BOTTOM_LEFT)) {
+            if (bottomLeftRegion == null) {
+                bottomLeftRegion = getRegion(CornerPosition.BOTTOM_LEFT);
+            }
+            if (!getChildren().contains(bottomLeftRegion)) {
+                getChildren().add(bottomLeftRegion);
+            }
+            bottomLeftRegion.relocate(0, getSkinnable().getHeight() - TRIANGLE_SIZE);
+        } else if (bottomLeftRegion != null) {
+            getChildren().remove(bottomLeftRegion);
+            bottomLeftRegion = null;
+        }
+    }
+
+    private static Region getRegion(CornerPosition position) {
+        Region region = new Region();
+        region.resize(TRIANGLE_SIZE, TRIANGLE_SIZE);
+        region.getStyleClass().add("cell-corner"); //$NON-NLS-1$
+        switch (position) {
+            case TOP_LEFT:
+                region.getStyleClass().add(TOP_LEFT_CLASS);
+                break;
+            case TOP_RIGHT:
+                region.getStyleClass().add(TOP_RIGHT_CLASS);
+                break;
+            case BOTTOM_RIGHT:
+                region.getStyleClass().add(BOTTOM_RIGHT_CLASS);
+                break;
+            case BOTTOM_LEFT:
+                region.getStyleClass().add(BOTTOM_LEFT_CLASS);
+                break;
+
+        }
+
+        return region;
+    }
+    
+    private final EventHandler<Event> triangleEventHandler = new EventHandler<Event>() {
+
+        @Override
+        public void handle(Event event) {
+            getSkinnable().requestLayout();
+        }
+    };
+    private final WeakEventHandler weakTriangleEventHandler = new WeakEventHandler(triangleEventHandler);
+
+    private final ChangeListener<SpreadsheetCell> itemChangeListener = new ChangeListener<SpreadsheetCell>() {
+        @Override
+        public void changed(ObservableValue<? extends SpreadsheetCell> arg0, SpreadsheetCell oldCell,
+                SpreadsheetCell newCell) {
+            if (oldCell != null) {
+                oldCell.removeEventHandler(SpreadsheetCell.CORNER_EVENT_TYPE, weakTriangleEventHandler);
+            }
+            if (newCell != null) {
+                newCell.addEventHandler(SpreadsheetCell.CORNER_EVENT_TYPE, weakTriangleEventHandler);
+            }
+            if (getSkinnable().getItem() != null) {
+                layoutTriangle();
+            }
+        }
+    };
+    private final WeakChangeListener<SpreadsheetCell> weakItemChangeListener = new WeakChangeListener<>(itemChangeListener);
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/FocusModelListener.java b/src/impl/org/controlsfx/spreadsheet/FocusModelListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..a359fb2dc0254b7feae0ed0f33736bc8a0ee0176
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/FocusModelListener.java
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2013, 2014 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ObservableList;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableView;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+/**
+ *
+ * The FocusModel Listener adapted to the SpreadsheetView regarding Span.
+ */
+public class FocusModelListener implements ChangeListener<TablePosition<ObservableList<SpreadsheetCell>, ?>> {
+
+    private final TableView.TableViewFocusModel<ObservableList<SpreadsheetCell>> tfm;
+    private final SpreadsheetGridView cellsView;
+    private final SpreadsheetView spreadsheetView;
+
+    /**
+     * Constructor.
+     *
+     * @param spreadsheetView
+     * @param cellsView
+     */
+    public FocusModelListener(SpreadsheetView spreadsheetView, SpreadsheetGridView cellsView) {
+        tfm = cellsView.getFocusModel();
+        this.spreadsheetView = spreadsheetView;
+        this.cellsView = cellsView;
+    }
+
+    @Override
+    public void changed(ObservableValue<? extends TablePosition<ObservableList<SpreadsheetCell>, ?>> ov,
+            final TablePosition<ObservableList<SpreadsheetCell>, ?> oldPosition,
+            final TablePosition<ObservableList<SpreadsheetCell>, ?> newPosition) {
+        final SpreadsheetView.SpanType spanType = spreadsheetView.getSpanType(newPosition.getRow(), newPosition.getColumn());
+        switch (spanType) {
+            case ROW_SPAN_INVISIBLE:
+                // If we notice that the new focused cell is the previous one,
+                // then it means that we were
+                // already on the cell and we wanted to go below.
+                if (!spreadsheetView.isPressed() && oldPosition.getColumn() == newPosition.getColumn() && oldPosition.getRow() == newPosition.getRow() - 1) {
+                    Platform.runLater(() -> {
+                        tfm.focus(getNextRowNumber(oldPosition, cellsView), oldPosition.getTableColumn());
+                    });
+
+                } else {
+                    // If the current focused cell if hidden by row span, we go
+                    // above
+                    Platform.runLater(() -> {
+                        tfm.focus(newPosition.getRow() - 1, newPosition.getTableColumn());
+                    });
+                }
+
+                break;
+            case BOTH_INVISIBLE:
+                // If the current focused cell if hidden by a both (row and
+                // column) span, we go left-above
+                Platform.runLater(() -> {
+                    tfm.focus(newPosition.getRow() - 1, cellsView.getColumns().get(newPosition.getColumn() - 1));
+                });
+                break;
+            case COLUMN_SPAN_INVISIBLE:
+                // If we notice that the new focused cell is the previous one,
+                // then it means that we were
+                // already on the cell and we wanted to go right.
+                if (!spreadsheetView.isPressed() && oldPosition.getColumn() == newPosition.getColumn() - 1 && oldPosition.getRow() == newPosition.getRow()) {
+
+                    Platform.runLater(() -> {
+                        tfm.focus(oldPosition.getRow(), getTableColumnSpan(oldPosition, cellsView));
+                    });
+                } else {
+                    // If the current focused cell if hidden by column span, we
+                    // go left
+
+                    Platform.runLater(() -> {
+                        tfm.focus(newPosition.getRow(), cellsView.getColumns().get(newPosition.getColumn() - 1));
+                    });
+                }
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Return the TableColumn right after the current TablePosition (including
+     * the ColumSpan to be on a visible Cell)
+     *
+     * @param t the current TablePosition
+     * @return
+     */
+    static TableColumn<ObservableList<SpreadsheetCell>, ?> getTableColumnSpan(final TablePosition<?, ?> t, SpreadsheetGridView cellsView) {
+        return cellsView.getVisibleLeafColumn(t.getColumn()
+                + cellsView.getItems().get(t.getRow()).get(t.getColumn()).getColumnSpan());
+    }
+
+    /**
+     * Return the Row number right after the current TablePosition (including
+     * the RowSpan to be on a visible Cell)
+     *
+     * @param pos
+     * @param cellsView
+     * @return
+     */
+    public static int getNextRowNumber(final TablePosition<?, ?> pos, TableView<ObservableList<SpreadsheetCell>> cellsView) {
+        return cellsView.getItems().get(pos.getRow()).get(pos.getColumn()).getRowSpan()
+                + cellsView.getItems().get(pos.getRow()).get(pos.getColumn()).getRow();
+    }
+    
+    public static int getPreviousRowNumber(final TablePosition<?, ?> pos, TableView<ObservableList<SpreadsheetCell>> cellsView) {
+        return cellsView.getItems().get(pos.getRow()).get(pos.getColumn()).getRow() -1;
+    }
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/GridCellEditor.java b/src/impl/org/controlsfx/spreadsheet/GridCellEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf5c01a92e6e467b110b06dd7861ee42c9db881c
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/GridCellEditor.java
@@ -0,0 +1,271 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.binding.Bindings;
+import javafx.beans.binding.BooleanExpression;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.Control;
+import javafx.scene.control.TextArea;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetCellEditor;
+import org.controlsfx.control.spreadsheet.SpreadsheetCellType;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+public class GridCellEditor {
+
+    /***************************************************************************
+     * * Protected/Private Fields * *
+     **************************************************************************/
+
+    private final SpreadsheetHandle handle;
+    // transient properties - these fields will change based on the current
+    // cell being edited.
+    private SpreadsheetCell modelCell;
+    private CellView viewCell;
+    private BooleanExpression focusProperty;
+
+    private boolean editing = false;
+    
+    //The cell's editor 
+    private SpreadsheetCellEditor spreadsheetCellEditor;
+    
+    //The last key pressed in order to select cell below if it was "enter"
+    private KeyCode lastKeyPressed;
+
+    /***************************************************************************
+     * * Constructor * *
+     **************************************************************************/
+
+    /**
+     * Construct the GridCellEditor.
+     */
+    public GridCellEditor(SpreadsheetHandle handle) {
+        this.handle = handle;
+    }
+
+    /***************************************************************************
+     * * Public Methods * *
+     **************************************************************************/
+    /**
+     * Update the internal {@link SpreadsheetCell}.
+     * 
+     * @param cell
+     */
+    public void updateDataCell(SpreadsheetCell cell) {
+        this.modelCell = cell;
+    }
+
+    /**
+     * Update the internal {@link CellView}
+     * 
+     * @param cell
+     */
+    public void updateSpreadsheetCell(CellView cell) {
+        this.viewCell = cell;
+    }
+
+    /**
+     * Update the SpreadsheetCellEditor
+     * 
+     * @param spreadsheetCellEditor
+     */
+    public void updateSpreadsheetCellEditor(final SpreadsheetCellEditor spreadsheetCellEditor) {
+        this.spreadsheetCellEditor = spreadsheetCellEditor;
+    }
+
+    /**
+     * Whenever you want to stop the edition, you call that method.<br/>
+     * True means you're trying to commit the value, then 
+     * {@link SpreadsheetCellType#match(java.lang.Object) } will be called 
+     * in order to verify that the value is correct.<br/>
+     * 
+     * False means you're trying to cancel the value and it will be follow by
+     * {@link #end()}.<br/>
+     * See SpreadsheetCellEditor description
+     * 
+     * @param commitValue true means commit, false means cancel
+     */
+    public void endEdit(boolean commitValue) { 
+        if (commitValue && editing) {
+            final SpreadsheetView view = handle.getView();
+            boolean match = modelCell.getCellType().match(spreadsheetCellEditor.getControlValue());
+
+            if (match && viewCell != null) {
+                Object value = modelCell.getCellType().convertValue(spreadsheetCellEditor.getControlValue());
+
+                // We update the value
+                view.getGrid().setCellValue(modelCell.getRow(), modelCell.getColumn(), value);
+                editing = false;
+                viewCell.commitEdit(modelCell);
+                end();
+                spreadsheetCellEditor.end();
+
+                //We select the cell below if "enter" was typed.
+                if (KeyCode.ENTER.equals(lastKeyPressed)) {
+                    handle.getView().getSelectionModel().clearAndSelectNextCell();
+                } else if (KeyCode.TAB.equals(lastKeyPressed)) {
+                    handle.getView().getSelectionModel().clearAndSelectRightCell();
+                    handle.getCellsViewSkin().scrollHorizontally();
+                }
+            }
+        }
+        
+        if (editing) {
+            editing = false;
+            if(viewCell != null){
+                viewCell.cancelEdit();
+            }
+            end();
+            if(spreadsheetCellEditor != null){
+                spreadsheetCellEditor.end();
+            }
+        }
+    }
+
+    /**
+     * Return if this editor is currently being used.
+     * 
+     * @return if this editor is being used.
+     */
+    public boolean isEditing() {
+        return editing;
+    }
+
+    public SpreadsheetCell getModelCell() {
+        return modelCell;
+    }
+
+    /***************************************************************************
+     * * Protected/Private Methods * *
+     **************************************************************************/
+    void startEdit() {
+        //If we do not reset this, it could false the endEdit behavior in case no key was pressed.
+        lastKeyPressed = null;
+        editing = true;
+        
+        handle.getGridView().addEventFilter(KeyEvent.KEY_PRESSED, enterKeyPressed);
+
+        handle.getCellsViewSkin().getVBar().valueProperty().addListener(endEditionListener);
+        handle.getCellsViewSkin().getHBar().valueProperty().addListener(endEditionListener);
+        
+        Control editor = spreadsheetCellEditor.getEditor();
+
+        // Then we call the user editor in order for it to be ready
+        Object value = modelCell.getItem();
+        //We don't want the editor to go beyond the cell boundaries
+        Double maxHeight = Math.min(viewCell.getHeight(), spreadsheetCellEditor.getMaxHeight());
+        
+        if (editor != null) {
+            viewCell.setGraphic(editor);
+            editor.setMaxHeight(maxHeight);
+            editor.setPrefWidth(viewCell.getWidth());
+        }
+
+        spreadsheetCellEditor.startEdit(value);
+        
+        if (editor != null) {
+            focusProperty = getFocusProperty(editor);
+            focusProperty.addListener(focusListener);
+        }
+        
+    }
+
+    private void end() {
+        if(focusProperty != null){
+            focusProperty.removeListener(focusListener);
+            focusProperty = null;
+        }
+        handle.getCellsViewSkin().getVBar().valueProperty().removeListener(endEditionListener);
+        handle.getCellsViewSkin().getHBar().valueProperty().removeListener(endEditionListener);
+        
+        handle.getGridView().removeEventFilter(KeyEvent.KEY_PRESSED, enterKeyPressed);
+
+        this.modelCell = null;
+        this.viewCell = null;
+    }
+
+    /**
+     * If we have a TextArea, we need to return a custom BooleanExpression
+     * because we want to let the editor in place even if the user is touching
+     * the scrollBars inside the textArea.
+     *
+     * @param control
+     * @return
+     */
+    private BooleanExpression getFocusProperty(Control control) {
+        if (control instanceof TextArea) {
+            return Bindings.createBooleanBinding(() -> {
+                if(handle.getView().getScene() == null){
+                    return false;
+                }
+                for (Node n = handle.getView().getScene().getFocusOwner(); n != null; n = n.getParent()) {
+                    if (n == control) {
+                        return true;
+                    }
+                }
+                return false;
+            }, handle.getView().getScene().focusOwnerProperty());
+        } else {
+            return control.focusedProperty();
+        }
+    }
+     
+    /**
+     * When we stop editing a cell, if enter was pressed, we want to go to the next line.
+     */
+    private final EventHandler<KeyEvent> enterKeyPressed = new EventHandler<KeyEvent>() {
+        @Override
+        public void handle(KeyEvent t) {
+            lastKeyPressed = t.getCode();
+        }
+    };
+    
+    private final ChangeListener<Boolean> focusListener = new ChangeListener<Boolean>() {
+        @Override
+        public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean isFocus) {
+            if (!isFocus) {
+                endEdit(true);
+            }
+        }
+    };
+    
+    private final InvalidationListener endEditionListener = new InvalidationListener() {
+        @Override
+        public void invalidated(Observable observable) {
+            endEdit(true);
+        }
+    };
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/GridRow.java b/src/impl/org/controlsfx/spreadsheet/GridRow.java
new file mode 100644
index 0000000000000000000000000000000000000000..bbffc04c5bdd81e7700c85174c386649bdf355da
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/GridRow.java
@@ -0,0 +1,161 @@
+/**
+ * Copyright (c) 2013, 2014 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.WeakInvalidationListener;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.collections.MapChangeListener;
+import javafx.collections.ObservableList;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.event.WeakEventHandler;
+import javafx.scene.control.Skin;
+import javafx.scene.control.TableRow;
+import javafx.scene.input.MouseEvent;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+
+/**
+ * 
+ * The tableRow which will holds the SpreadsheetCell.
+ */
+public class GridRow extends TableRow<ObservableList<SpreadsheetCell>> {
+
+    /***************************************************************************
+     * * Private Fields * *
+     **************************************************************************/
+    private final SpreadsheetHandle handle;
+    /**
+     * When the row is fixed, it may have a shift from its original position
+     * which we need in order to layout the cells properly and also for the
+     * rectangle selection.
+     */
+    DoubleProperty verticalShift = new SimpleDoubleProperty();
+
+    /***************************************************************************
+     * * Constructor * *
+     **************************************************************************/
+    public GridRow(SpreadsheetHandle handle) {
+        super();
+        this.handle = handle;
+      
+        /**
+         *  FIXME Bug? When re-using the row, it should re-compute the prefHeight and not
+         *  keep the old value.
+         */
+        this.indexProperty().addListener(weakPrefHeightListener);
+        this.visibleProperty().addListener(weakPrefHeightListener);
+        
+        handle.getView().gridProperty().addListener(weakPrefHeightListener);
+        
+        /**
+         * When the height is changing elsewhere, we need to update ourself if necessary.
+         */
+        handle.getCellsViewSkin().rowHeightMap.addListener(new MapChangeListener<Integer, Double>() {
+
+            @Override
+            public void onChanged(MapChangeListener.Change<? extends Integer, ? extends Double> change) {
+                if (change.wasAdded() && change.getKey() == getIndex()) {
+                    setRowHeight(change.getValueAdded());
+                } else if (change.wasRemoved() && change.getKey() == getIndex()) {
+                    setRowHeight(computePrefHeight(-1));
+                }
+            }
+        });
+        /**
+         * When we are adding deported cells (fixed in columns) into a row via
+         * addCell. The cell is not receiving the DRAG_DETECTED eventHandler
+         * because it's the row that receives it first. If it's the case, we
+         * must give the event to the cell underneath.
+         */
+        this.addEventHandler(MouseEvent.DRAG_DETECTED, weakDragHandler);
+    }
+    /***************************************************************************
+     * * Protected Methods * *
+     **************************************************************************/
+
+    void addCell(CellView cell) {
+        getChildren().add(cell);
+    }
+
+    void removeCell(CellView gc) {
+        getChildren().remove(gc);
+    }
+    
+    SpreadsheetView getSpreadsheetView() {
+        return handle.getView();
+    }
+
+    @Override
+    protected double computePrefHeight(double width) {
+        return handle.getCellsViewSkin().getRowHeight(getIndex());
+    }
+    
+    @Override
+    protected double computeMinHeight(double width) {
+        return handle.getCellsViewSkin().getRowHeight(getIndex());
+    }
+    
+    @Override
+    protected Skin<?> createDefaultSkin() {
+        return new GridRowSkin(handle, this);
+    }
+    
+    private final InvalidationListener setPrefHeightListener = new InvalidationListener() {
+
+        @Override
+        public void invalidated(Observable o) {
+            setRowHeight(computePrefHeight(-1));
+        }
+    };
+    
+    private final WeakInvalidationListener weakPrefHeightListener = new WeakInvalidationListener(setPrefHeightListener);
+    
+    public void setRowHeight(double height) {
+        CellView.getValue(() -> {
+            setHeight(height);
+        });
+        
+        setPrefHeight(height);
+        handle.getCellsViewSkin().rectangleSelection.updateRectangle();
+    }
+    
+    private final EventHandler<MouseEvent> dragDetectedEventHandler = new EventHandler<MouseEvent>() {
+        @Override
+        public void handle(MouseEvent event) {
+            if (event.getTarget().getClass().equals(GridRow.class) && event.getPickResult().getIntersectedNode() != null) {
+                Event.fireEvent(event.getPickResult().getIntersectedNode(), event);
+            }
+        }
+    };
+
+    private final WeakEventHandler<MouseEvent> weakDragHandler = new WeakEventHandler(dragDetectedEventHandler);
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/GridRowSkin.java b/src/impl/org/controlsfx/spreadsheet/GridRowSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..a0bd3d17ffe64e6780889a1ac9b0499b70ab9c57
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/GridRowSkin.java
@@ -0,0 +1,615 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import com.sun.javafx.scene.control.behavior.CellBehaviorBase;
+import com.sun.javafx.scene.control.behavior.TableRowBehavior;
+import com.sun.javafx.scene.control.skin.CellSkinBase;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javafx.collections.ObservableList;
+import javafx.scene.Node;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumnBase;
+import javafx.scene.control.TableRow;
+import org.controlsfx.control.spreadsheet.Grid;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetColumn;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+public class GridRowSkin extends CellSkinBase<TableRow<ObservableList<SpreadsheetCell>>, CellBehaviorBase<TableRow<ObservableList<SpreadsheetCell>>>> {
+
+    private final SpreadsheetHandle handle;
+    private final SpreadsheetView spreadsheetView;
+
+    private Reference<HashMap<TableColumnBase, CellView>> cellsMap;
+
+    private final List<CellView> cells = new ArrayList<>();
+
+    public GridRowSkin(SpreadsheetHandle handle, TableRow<ObservableList<SpreadsheetCell>> gridRow) {
+        super(gridRow, new TableRowBehavior<>(gridRow));
+        this.handle = handle;
+        spreadsheetView = handle.getView();
+
+        getSkinnable().setPickOnBounds(false);
+
+        registerChangeListener(gridRow.itemProperty(), "ITEM");
+        registerChangeListener(gridRow.indexProperty(), "INDEX");
+    }
+
+    @Override
+    protected void handleControlPropertyChanged(String p) {
+        super.handleControlPropertyChanged(p);
+
+        if ("INDEX".equals(p)) {
+            // Fix for RT-36661, where empty table cells were showing content, as they
+            // had incorrect table cell indices (but the table row index was correct).
+            // Note that we only do the update on empty cells to avoid the issue
+            // noted below in requestCellUpdate().
+            if (getSkinnable().isEmpty()) {
+                requestCellUpdate();
+            }
+        } else if ("ITEM".equals(p)) {
+            requestCellUpdate();
+        } else if ("FIXED_CELL_SIZE".equals(p)) {
+//            fixedCellSize = fixedCellSizeProperty().get();
+//            fixedCellSizeEnabled = fixedCellSize > 0;
+        }
+    }
+
+    private void requestCellUpdate() {
+        getSkinnable().requestLayout();
+
+        // update the index of all children cells (RT-29849).
+        // Note that we do this after the TableRow item has been updated,
+        // rather than when the TableRow index has changed (as this will be
+        // before the row has updated its item). This will result in the
+        // issue highlighted in RT-33602, where the table cell had the correct
+        // item whilst the row had the old item.
+        final int newIndex = getSkinnable().getIndex();
+        /**
+         * When the index is changing, we need to clear out all the children
+         * because we may end up with useless cell in the row.
+         */
+        getChildren().clear();
+        for (int i = 0, max = cells.size(); i < max; i++) {
+            cells.get(i).updateIndex(newIndex);
+        }
+    }
+
+    @Override
+    protected void layoutChildren(double x, final double y, final double w, final double h) {
+
+        final ObservableList<? extends TableColumnBase<?, ?>> visibleLeafColumns = handle.getGridView().getVisibleLeafColumns();
+        if (visibleLeafColumns.isEmpty()) {
+            super.layoutChildren(x, y, w, h);
+            return;
+        }
+
+        final GridRow control = (GridRow) getSkinnable();
+        final SpreadsheetGridView gridView = (SpreadsheetGridView) handle.getGridView();
+        final Grid grid = spreadsheetView.getGrid();
+        final int index = control.getIndex();
+
+        /**
+         * If this row is out of bounds, this means that the row is displayed
+         * either at the top or at the bottom. In any case, this row is not
+         * meant to be seen so we clear its children list in order not to show
+         * previous TableCell that could be there.
+         */
+        if (index < 0 || index >= gridView.getItems().size()) {
+            getChildren().clear();
+            putCellsInCache();
+            return;
+        }
+
+        final List<SpreadsheetCell> row = grid.getRows().get(index);
+        final List<SpreadsheetColumn> columns = spreadsheetView.getColumns();
+        final ObservableList<TableColumn<ObservableList<SpreadsheetCell>, ?>> tableViewColumns = gridView.getColumns();
+        /**
+         * If we use "setGrid" on SpreadsheetView, we must be careful because we
+         * set our columns after (due to threading safety). So if, by mistake,
+         * we are in layout and the columns are set in SpreadsheetView, but not
+         * in TableView (yet). Then just return and wait for next calling.
+         */
+        if (columns.size() != tableViewColumns.size()) {
+            return;
+        }
+
+        getSkinnable().setVisible(true);
+        // layout the individual column cells
+        double width;
+        double height;
+
+        final double verticalPadding = snappedTopInset() + snappedBottomInset();
+        final double horizontalPadding = snappedLeftInset()
+                + snappedRightInset();
+        /**
+         * Here we make the distinction between the official controlHeight and
+         * the customHeight that we may apply.
+         */
+        double controlHeight = getTableRowHeight(index);
+        double customHeight = controlHeight == Grid.AUTOFIT ? GridViewSkin.DEFAULT_CELL_HEIGHT : controlHeight;
+
+        final GridViewSkin skin = handle.getCellsViewSkin();
+        skin.hBarValue.set(index, true);
+
+        // determine the width of the visible portion of the table
+        double headerWidth = gridView.getWidth();
+        final double hbarValue = skin.getHBar().getValue();
+
+        /**
+         * FOR FIXED ROWS
+         */
+        ((GridRow) getSkinnable()).verticalShift.setValue(getFixedRowShift(index));
+
+        double fixedColumnWidth = 0;
+        List<CellView> fixedCells = new ArrayList();
+
+        //We compute the cells here
+        putCellsInCache();
+
+        boolean firstVisibleCell = false;
+        CellView lastCell = null;
+        boolean needToBeShifted;
+        boolean rowHeightChange = false;
+        for (int indexColumn = 0; indexColumn < columns.size(); indexColumn++) {
+
+            width = snapSize(columns.get(indexColumn).getWidth()) - snapSize(horizontalPadding);
+
+            final SpreadsheetCell spreadsheetCell = row.get(indexColumn);
+            boolean isVisible = !isInvisible(x, width, hbarValue, headerWidth, spreadsheetCell.getColumnSpan());
+
+            if (columns.get(indexColumn).isFixed()) {
+                isVisible = true;
+            }
+
+            if (!isVisible) {
+                if (firstVisibleCell) {
+                    break;
+                }
+                x += width;
+                continue;
+            }
+            final CellView tableCell = getCell(gridView.getColumns().get(indexColumn));
+
+            cells.add(0, tableCell);
+
+            // In case the node was treated previously
+            tableCell.setManaged(true);
+
+            /**
+             * FOR FIXED COLUMNS
+             */
+            double tableCellX = 0;
+
+            /**
+             * We need to update the fixedColumnWidth only on visible cell and
+             * we need to add the full width including the span.
+             *
+             * If we fail to do so, we may be in the situation where x will grow
+             * with the correct width and not fixedColumnWidth. Thus some cell
+             * that should be shifted will not because the computation based on
+             * fixedColumnWidth will be wrong.
+             */
+            boolean increaseFixedWidth = false;
+            //Virtualization of column
+            // We translate that column by the Hbar Value if it's fixed
+            if (columns.get(indexColumn).isFixed()) {
+                if (hbarValue + fixedColumnWidth > x && spreadsheetCell.getColumn() == indexColumn) {
+                    increaseFixedWidth = true;
+                    tableCellX = Math.abs(hbarValue - x + fixedColumnWidth);
+//                	 tableCell.toFront();
+                    fixedColumnWidth += width;
+//                    isVisible = true; // If in fixedColumn, it's obviously visible
+                    fixedCells.add(tableCell);
+                }
+            }
+
+            if (isVisible) {
+                final SpreadsheetView.SpanType spanType = grid.getSpanType(spreadsheetView, index, indexColumn);
+
+                switch (spanType) {
+                    case ROW_SPAN_INVISIBLE:
+                    case BOTH_INVISIBLE:
+                        fixedCells.remove(tableCell);
+                        getChildren().remove(tableCell);
+//                        cells.remove(tableCell);
+                        x += width;
+                        continue; // we don't want to fall through
+                    case COLUMN_SPAN_INVISIBLE:
+                        fixedCells.remove(tableCell);
+                        getChildren().remove(tableCell);
+//                        cells.remove(tableCell);
+                        continue; // we don't want to fall through
+                    case ROW_VISIBLE:
+//                        final TableViewSpanSelectionModel sm = (TableViewSpanSelectionModel) handle.getGridView().getSelectionModel();
+//                        final TableColumn<ObservableList<SpreadsheetCell>, ?> col = tableViewColumns.get(indexColumn);
+
+                    /**
+                     * In case this cell was selected before but we scroll
+                     * up/down and it's invisible now. It has to pass his
+                         * "selected property" to the new Cell in charge of
+                         * spanning
+                     */
+//                        final TablePosition<ObservableList<SpreadsheetCell>, ?> selectedPosition = sm.isSelectedRange(index, col, indexColumn);
+                    // If the selected cell is in the same row, no need to re-select it
+//                        if (selectedPosition != null
+//                                //When shift selecting, all cells become ROW_VISIBLE so
+//                                //We avoid loop selecting here
+//                                && skin.containsRow(index)
+//                                && selectedPosition.getRow() != index) {
+//                            sm.clearSelection(selectedPosition.getRow(),
+//                                    selectedPosition.getTableColumn());
+//                            sm.select(index, col);
+//                        }
+                    case NORMAL_CELL: // fall through and carry on
+                        if (tableCell.getIndex() != index) {
+                            tableCell.updateIndex(index);
+                        } else {
+                            tableCell.updateItem(spreadsheetCell, false);
+                        }
+                        /**
+                         * Here we need to add the cells on the first position
+                         * because this row may contain some deported cells from
+                         * other rows in order to be on top in term of z-order.
+                         * So the cell we're currently adding must not recover
+                         * them.
+                         */
+                        if (tableCell.getParent() == null) {
+                            getChildren().add(0, tableCell);
+                        }
+                }
+
+                if (spreadsheetCell.getColumnSpan() > 1) {
+                    /**
+                     * we need to span multiple columns, so we sum up the width
+                     * of the additional columns, adding it to the width
+                     * variable
+                     */
+                    for (int i = 1, colSpan = spreadsheetCell.getColumnSpan(), max1 = columns
+                            .size() - indexColumn; i < colSpan && i < max1; i++) {
+                        double tempWidth = snapSize(columns.get(indexColumn + i).getWidth());
+                        width += tempWidth;
+                        if (increaseFixedWidth) {
+                            fixedColumnWidth += tempWidth;
+                        }
+                    }
+                }
+
+                /**
+                 * If we are in autofit and the prefHeight of this cell is
+                 * superior to the default cell height. Then we will use this
+                 * new height for row's height.
+                 *
+                 * We then need to apply the value to previous cell, and also
+                 * layout the children because since we are layouting upward,
+                 * next rows needs to know that this row is bigger than usual.
+                 */
+                if (controlHeight == Grid.AUTOFIT && !tableCell.isEditing()) {
+                    double tempHeight = tableCell.prefHeight(width);
+                    if (tempHeight > customHeight) {
+                        rowHeightChange = true;
+                        skin.rowHeightMap.put(index, tempHeight);
+                        for (CellView cell : cells) {
+                            /**
+                             * We need to add the difference between the
+                             * previous height and the new height. If we were
+                             * just setting the new height, the row spanning
+                             * cell would be shorter. That's why we need to use
+                             * the cell height.
+                             */
+                            cell.resize(cell.getWidth(), cell.getHeight() + (tempHeight - customHeight));
+                        }
+                        customHeight = tempHeight;
+                        skin.getFlow().layoutChildren();
+                    }
+                }
+
+                height = customHeight;
+                height = snapSize(height) - snapSize(verticalPadding);
+                /**
+                 * We need to span multiple rows, so we sum up the height of all
+                 * the rows. The height of the current row is ignored and the
+                 * whole value is computed.
+                 */
+                if (spreadsheetCell.getRowSpan() > 1) {
+                    height = 0;
+                    final int maxRow = spreadsheetCell.getRow() + spreadsheetCell.getRowSpan();
+                    for (int i = spreadsheetCell.getRow(); i < maxRow; ++i) {
+                        height += snapSize(skin.getRowHeight(i));
+                    }
+                }
+
+                //Fix for JDK-8146406
+                needToBeShifted = false;
+                /**
+                 * If the current cell has no left border, and the previous cell
+                 * had no right border, and we're fixed. We may have the problem
+                 * where there is a tiny gap between the cells when scrolling
+                 * horizontally. Thus we must enlarge this cell a bit, and shift
+                 * it a bit in order to mask that gap. If the cell has a border
+                 * defined, the problem seems not to happen.
+                 */
+                if (spreadsheetView.getFixedRows().contains(index) 
+                        && lastCell != null 
+                        && !hasRightBorder(lastCell)
+                        && !hasLeftBorder(tableCell)) {
+                    tableCell.resize(width +1, height);
+                    needToBeShifted = true;
+                } else {
+                    tableCell.resize(width, height);
+                }
+                lastCell = tableCell;
+                // We want to place the layout always at the starting cell.
+                double spaceBetweenTopAndMe = 0;
+                for (int p = spreadsheetCell.getRow(); p < index; ++p) {
+                    spaceBetweenTopAndMe += skin.getRowHeight(p);
+                }
+
+                tableCell.relocate(x + tableCellX + (needToBeShifted? -1 : 0), snappedTopInset()
+                        - spaceBetweenTopAndMe + ((GridRow) getSkinnable()).verticalShift.get());
+
+                // Request layout is here as (partial) fix for RT-28684
+//                 tableCell.requestLayout();
+            } else {
+                getChildren().remove(tableCell);
+            }
+            x += width;
+        }
+        skin.fixedColumnWidth = fixedColumnWidth;
+        handleFixedCell(fixedCells, index);
+        removeUselessCell(index);
+        if (handle.getCellsViewSkin().lastRowLayout.get() == true) {
+            handle.getCellsViewSkin().lastRowLayout.setValue(false);
+        }
+        /**
+         * If we modified an height here, ROW_HEIGHT_CHANGE will not be
+         * triggered, because it's not the user who has modified that. So the
+         * rectangle will not update, we need to force it here.
+         */
+        if (rowHeightChange && spreadsheetView.getFixedRows().contains(index)) {
+            skin.computeFixedRowHeight();
+        }
+    }
+
+    private boolean hasRightBorder(CellView tableCell) {
+        return tableCell.getBorder() != null 
+                && !tableCell.getBorder().isEmpty() 
+                && tableCell.getBorder().getStrokes().get(0).getWidths().getRight() > 0;
+    }
+    
+    private boolean hasLeftBorder(CellView tableCell) {
+        return tableCell.getBorder() != null 
+                && !tableCell.getBorder().isEmpty() 
+                && tableCell.getBorder().getStrokes().get(0).getWidths().getLeft()> 0;
+    }
+
+    /**
+     * Here we want to remove of the sceneGraph cells that are not used.
+     *
+     * Before we were removing the cells that we were getting from the cache.
+     * But that is not enough because some cells can be added somehow, and stay
+     * within the row. Since we do not often clear the children because of some
+     * deportedCell present inside, we must use that Predicate to clear all
+     * CellView not contained in cells and with the same index. Thus we preserve
+     * the deported cell.
+     */
+    private void removeUselessCell(int index) {
+        getChildren().removeIf((Node t) -> {
+            if (t instanceof CellView) {
+                return !cells.contains(t) && ((CellView) t).getIndex() == index;
+            }
+            return false;
+        });
+    }
+
+    /**
+     * This handles the fixed cells in column.
+     *
+     * @param fixedCells
+     * @param index
+     */
+    private void handleFixedCell(List<CellView> fixedCells, int index) {
+        if (fixedCells.isEmpty()) {
+            return;
+        }
+
+        /**
+         * If we have a fixedCell (in column) and that cell may be recovered by
+         * a rowSpan, we want to put that tableCell ahead in term of z-order. So
+         * we need to put it in another row.
+         */
+        if (handle.getCellsViewSkin().rowToLayout.get(index)) {
+            GridRow gridRow = handle.getCellsViewSkin().getFlow().getTopRow();
+            if (gridRow != null) {
+                for (CellView cell : fixedCells) {
+                    final double originalLayoutY = getSkinnable().getLayoutY() + cell.getLayoutY();
+                    gridRow.removeCell(cell);
+                    gridRow.addCell(cell);
+                    if (handle.getCellsViewSkin().deportedCells.containsKey(gridRow)) {
+                        handle.getCellsViewSkin().deportedCells.get(gridRow).add(cell);
+                    } else {
+                        Set<CellView> temp = new HashSet<>();
+                        temp.add(cell);
+                        handle.getCellsViewSkin().deportedCells.put(gridRow, temp);
+                    }
+                    /**
+                     * I need to have the layoutY of the original row, but also
+                     * to remove the layoutY of the row I'm adding in. Because
+                     * if the first row is fixed and is undergoing a bit of
+                     * translate in order to be visible, we need to remove that
+                     * "bit of translate".
+                     */
+                    cell.relocate(cell.getLayoutX(), originalLayoutY - gridRow.getLayoutY());
+                }
+            }
+        } else {
+            for (CellView cell : fixedCells) {
+                cell.toFront();
+            }
+        }
+    }
+
+    /**
+     * Return the Cache. Here we use a WeakReference because the WeakHashMap is
+     * not working. TableCell added to it are not removed if the GC wants them.
+     * So we put the whole cache in WeakReference. In normal condition, the
+     * cache is not trashed that much and is efficient. In the case where the
+     * user scroll horizontally a lot, that cache can then be trashed in order
+     * to avoid OutOfMemoryError.
+     *
+     * @return
+     */
+    private HashMap<TableColumnBase, CellView> getCellsMap() {
+        if (cellsMap == null || cellsMap.get() == null) {
+            HashMap<TableColumnBase, CellView> map = new HashMap<>();
+            cellsMap = new WeakReference<>(map);
+            return map;
+        }
+        return cellsMap.get();
+    }
+
+    /**
+     * This will put all current displayed cell into the cache.
+     */
+    private void putCellsInCache() {
+        for (CellView cell : cells) {
+            getCellsMap().put(cell.getTableColumn(), cell);
+        }
+        cells.clear();
+    }
+
+    /**
+     * This will retrieve a cell for the specified column. If the cell exists in
+     * the cache, it's extracted from it. Otherwise, a cell is created.
+     *
+     * @param tcb
+     * @return
+     */
+    private CellView getCell(TableColumnBase tcb) {
+        TableColumn tableColumn = (TableColumn<CellView, ?>) tcb;
+        CellView cell;
+        if (getCellsMap().containsKey(tableColumn)) {
+            return getCellsMap().remove(tableColumn);
+        } else {
+            cell = (CellView) tableColumn.getCellFactory().call(tableColumn);
+            cell.updateTableColumn(tableColumn);
+            cell.updateTableView(tableColumn.getTableView());
+            cell.updateTableRow(getSkinnable());
+        }
+        return cell;
+    }
+
+    /**
+     * Return the space we need to shift that row if it's fixed. Also update the {@link GridViewSkin#getCurrentlyFixedRow()
+     * } .
+     *
+     * @param index
+     * @return
+     */
+    private double getFixedRowShift(int index) {
+        double tableCellY = 0;
+        int positionY = spreadsheetView.getFixedRows().indexOf(index);
+
+        //FIXME Integrate if fixedCellSize is enabled
+        //Computing how much space we need to translate
+        //because each row has different space.
+        double space = 0;
+        for (int o = 0; o < positionY; ++o) {
+            space += handle.getCellsViewSkin().getRowHeight(spreadsheetView.getFixedRows().get(o));
+        }
+
+        //If true, this row is fixed
+        if (positionY != -1 && getSkinnable().getLocalToParentTransform().getTy() <= space) {
+            //This row is a bit hidden on top so we translate then for it to be fully visible
+            tableCellY = space - getSkinnable().getLocalToParentTransform().getTy();
+            handle.getCellsViewSkin().getCurrentlyFixedRow().add(index);
+        } else {
+            handle.getCellsViewSkin().getCurrentlyFixedRow().remove(index);
+        }
+        return tableCellY;
+    }
+
+    /**
+     * Return the height of a row.
+     *
+     * @param row
+     * @return
+     */
+    private double getTableRowHeight(int row) {
+        Double rowHeightCache = handle.getCellsViewSkin().rowHeightMap.get(row);
+        return rowHeightCache == null ? handle.getView().getGrid().getRowHeight(row) : rowHeightCache;
+    }
+
+    /**
+     * Return true if the current cell is part of the sceneGraph.
+     *
+     * @param x beginning of the cell
+     * @param width total width of the cell
+     * @param hbarValue
+     * @param headerWidth width of the visible portion of the tableView
+     * @param columnSpan
+     * @return
+     */
+    private boolean isInvisible(double x, double width, double hbarValue,
+            double headerWidth, int columnSpan) {
+        return (x + width < hbarValue && columnSpan == 1) || (x > hbarValue + headerWidth);
+    }
+
+    @Override
+    protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        double prefWidth = 0.0;
+
+        final List<? extends TableColumnBase/*<T,?>*/> visibleLeafColumns = handle.getGridView().getVisibleLeafColumns();
+        for (int i = 0, max = visibleLeafColumns.size(); i < max; i++) {
+            prefWidth += visibleLeafColumns.get(i).getWidth();
+        }
+
+        return prefWidth;
+    }
+
+    @Override
+    protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return getSkinnable().getPrefHeight();
+    }
+
+    @Override
+    protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return getSkinnable().getPrefHeight();
+    }
+
+    @Override
+    protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        return super.computeMaxHeight(width, topInset, rightInset, bottomInset, leftInset);
+    }
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/GridViewBehavior.java b/src/impl/org/controlsfx/spreadsheet/GridViewBehavior.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ef5a8395f8cee5d61fae39956869c5bcf0b8a24
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/GridViewBehavior.java
@@ -0,0 +1,509 @@
+/**
+ * Copyright (c) 2015 ControlsFX All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met: *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. * Redistributions in binary
+ * form must reproduce the above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or other materials provided
+ * with the distribution. * Neither the name of ControlsFX, any associated
+ * website, nor the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import com.sun.javafx.scene.control.behavior.TableViewBehavior;
+import javafx.collections.ObservableList;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.TableColumnBase;
+import javafx.scene.control.TableFocusModel;
+import javafx.scene.control.TablePositionBase;
+import javafx.scene.control.TableSelectionModel;
+import javafx.scene.control.TableView;
+import javafx.util.Pair;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+
+/**
+ *
+ * This overrides {@link TableViewBehavior} in order to modify the selection
+ * behavior. The selection will basically work like Excel:
+ *
+ * Selection will always be rectangles. So selection by SHIFT will produce a
+ * rectangle extending your selection.
+ *
+ * Pressing SHORTCUT with an arrow will on a cell will do:
+ *
+ * - If the cell is empty, we go to the next (in the direction) non empty cell.
+ *
+ * - If the cell is not empty, then we either go to the last non empty cell if
+ * the next is not empty, or the first non empty cell if the next is empty.
+ *
+ * This is meant to increase navigation on non empty cell in a Spreadsheet more
+ * easily.
+ *
+ * Pressing SHORTCUT and SHIFT together will behave as the ShortCut previously
+ * explained but the selection will be extended instead of just selecting the
+ * new cell.
+ *
+ */
+public class GridViewBehavior extends TableViewBehavior<ObservableList<SpreadsheetCell>> {
+
+    private GridViewSkin skin;
+
+    public GridViewBehavior(TableView<ObservableList<SpreadsheetCell>> control) {
+        super(control);
+    }
+
+    void setGridViewSkin(GridViewSkin skin) {
+        this.skin = skin;
+    }
+
+    @Override
+    protected void updateCellVerticalSelection(int delta, Runnable defaultAction) {
+        TableViewSpanSelectionModel sm = (TableViewSpanSelectionModel) getSelectionModel();
+        if (sm == null || sm.getSelectionMode() == SelectionMode.SINGLE) {
+            return;
+        }
+
+        TableFocusModel fm = getFocusModel();
+        if (fm == null) {
+            return;
+        }
+
+        final TablePositionBase focusedCell = getFocusedCell();
+
+        if (isShiftDown && getAnchor() != null) {
+
+            final SpreadsheetCell cell = getControl().getItems().get(fm.getFocusedIndex()).get(focusedCell.getColumn());
+            sm.direction = new Pair<>(delta, 0);
+            /**
+             * If the delta is >0, it means we want to go down, so we need to
+             * target the cell that is after our cell. So we need to take the
+             * last row of our cell if spanning. If the delta is < 0, it means
+             * we want to go up, so we just take the row.
+             */
+            int newRow;
+            if (delta < 0) {
+                newRow = cell.getRow() + delta;
+            } else {
+                newRow = cell.getRow() + cell.getRowSpan() - 1 + delta;
+            }
+
+            // we don't let the newRow go outside the bounds of the data
+            newRow = Math.max(Math.min(getItemCount() - 1, newRow), 0);
+
+            final TablePositionBase<?> anchor = getAnchor();
+            int minRow = Math.min(anchor.getRow(), newRow);
+            int maxRow = Math.max(anchor.getRow(), newRow);
+            int minColumn = Math.min(anchor.getColumn(), focusedCell.getColumn());
+            int maxColumn = Math.max(anchor.getColumn(), focusedCell.getColumn());
+
+            sm.clearSelection();
+            if (minColumn != -1 && maxColumn != -1) {
+                sm.selectRange(minRow, getControl().getColumns().get(minColumn), maxRow,
+                        getControl().getColumns().get(maxColumn));
+            }
+            fm.focus(newRow, focusedCell.getTableColumn());
+        } else {
+            final int focusIndex = fm.getFocusedIndex();
+            if (!sm.isSelected(focusIndex, focusedCell.getTableColumn())) {
+                sm.select(focusIndex, focusedCell.getTableColumn());
+            }
+            defaultAction.run();
+        }
+    }
+
+    @Override
+    protected void updateCellHorizontalSelection(int delta, Runnable defaultAction) {
+        TableViewSpanSelectionModel sm = (TableViewSpanSelectionModel) getSelectionModel();
+        if (sm == null || sm.getSelectionMode() == SelectionMode.SINGLE) {
+            return;
+        }
+
+        TableFocusModel fm = getFocusModel();
+        if (fm == null) {
+            return;
+        }
+
+        final TablePositionBase focusedCell = getFocusedCell();
+        if (focusedCell == null || focusedCell.getTableColumn() == null) {
+            return;
+        }
+
+        TableColumnBase adjacentColumn = getColumn(focusedCell.getTableColumn(), delta);
+        if (adjacentColumn == null) {
+            return;
+        }
+
+        final int focusedCellRow = focusedCell.getRow();
+
+        if (isShiftDown && getAnchor() != null) {
+            final int columnPos = getVisibleLeafIndex(focusedCell.getTableColumn());
+
+            final SpreadsheetCell cell = getControl().getItems().get(focusedCellRow).get(columnPos);
+            
+            sm.direction = new Pair<>(0, delta);
+            final int newColumn;// = columnCell + delta;
+            if (delta < 0) {
+                newColumn = cell.getColumn() + delta;
+            } else {
+                newColumn = cell.getColumn() + cell.getColumnSpan() - 1 + delta;
+            }
+            final TablePositionBase<?> anchor = getAnchor();
+            int minRow = Math.min(anchor.getRow(), focusedCellRow);
+            int maxRow = Math.max(anchor.getRow(), focusedCellRow);
+            int minColumn = Math.min(anchor.getColumn(), newColumn);
+            int maxColumn = Math.max(anchor.getColumn(), newColumn);
+
+            sm.clearSelection();
+            if (minColumn != -1 && maxColumn != -1) {
+                sm.selectRange(minRow, getControl().getColumns().get(minColumn), maxRow,
+                        getControl().getColumns().get(maxColumn));
+            }
+            fm.focus(focusedCell.getRow(), getColumn(newColumn));
+        } else {
+            defaultAction.run();
+        }
+
+    }
+
+    @Override
+    protected void focusPreviousRow() {
+        focusVertical(true);
+    }
+
+    @Override
+    protected void focusNextRow() {
+        focusVertical(false);
+    }
+
+    @Override
+    protected void focusLeftCell() {
+        focusHorizontal(true);
+    }
+
+    @Override
+    protected void focusRightCell() {
+        focusHorizontal(false);
+    }
+
+    @Override
+    protected void discontinuousSelectPreviousRow() {
+        discontinuousSelectVertical(true);
+    }
+
+    @Override
+    protected void discontinuousSelectNextRow() {
+        discontinuousSelectVertical(false);
+    }
+
+    @Override
+    protected void discontinuousSelectPreviousColumn() {
+        discontinuousSelectHorizontal(true);
+    }
+
+    @Override
+    protected void discontinuousSelectNextColumn() {
+        discontinuousSelectHorizontal(false);
+    }
+
+    private void focusVertical(boolean previous) {
+        TableSelectionModel sm = getSelectionModel();
+        if (sm == null || sm.getSelectionMode() == SelectionMode.SINGLE) {
+            return;
+        }
+
+        TableFocusModel fm = getFocusModel();
+        if (fm == null) {
+            return;
+        }
+
+        final TablePositionBase focusedCell = getFocusedCell();
+        if (focusedCell == null || focusedCell.getTableColumn() == null) {
+            return;
+        }
+
+        final SpreadsheetCell cell = getControl().getItems().get(focusedCell.getRow()).get(focusedCell.getColumn());
+        sm.clearAndSelect(previous ? findPreviousRow(focusedCell, cell) : findNextRow(focusedCell, cell), focusedCell.getTableColumn());
+        skin.focusScroll();
+    }
+
+    private void focusHorizontal(boolean previous) {
+        TableSelectionModel sm = getSelectionModel();
+        if (sm == null) {
+            return;
+        }
+
+        TableFocusModel fm = getFocusModel();
+        if (fm == null) {
+            return;
+        }
+        final TablePositionBase focusedCell = getFocusedCell();
+        if (focusedCell == null || focusedCell.getTableColumn() == null) {
+            return;
+        }
+
+        final SpreadsheetCell cell = getControl().getItems().get(focusedCell.getRow()).get(focusedCell.getColumn());
+
+        sm.clearAndSelect(focusedCell.getRow(), getControl().getColumns().get(previous ? findPreviousColumn(focusedCell, cell) : findNextColumn(focusedCell, cell)));
+        skin.focusScroll();
+    }
+
+    private int findPreviousRow(TablePositionBase focusedCell, SpreadsheetCell cell) {
+        final ObservableList<ObservableList<SpreadsheetCell>> items = getControl().getItems();
+        SpreadsheetCell temp;
+        //If my cell is empty, I seek the next non-empty
+        if (isEmpty(cell)) {
+            for (int row = focusedCell.getRow() - 1; row >= 0; --row) {
+                temp = items.get(row).get(focusedCell.getColumn());
+                if (!isEmpty(temp)) {
+                    return row;
+                }
+            }
+        } else if (focusedCell.getRow() - 1 >= 0 && !isEmpty(items.get(focusedCell.getRow() - 1).get(focusedCell.getColumn()))) {
+            for (int row = focusedCell.getRow() - 2; row >= 0; --row) {
+                temp = items.get(row).get(focusedCell.getColumn());
+                if (isEmpty(temp)) {
+                    return row + 1;
+                }
+            }
+        } else {
+            //If I'm not empty and the next is empty, I seek the first non empty
+            for (int row = focusedCell.getRow() - 2; row >= 0; --row) {
+                temp = items.get(row).get(focusedCell.getColumn());
+                if (!isEmpty(temp)) {
+                    return row;
+                }
+            }
+        }
+
+        //If we're here, we then select the last on
+        return 0;
+    }
+
+    
+    @Override
+    protected void selectCell(int rowDiff, int columnDiff) {
+        TableViewSpanSelectionModel sm = (TableViewSpanSelectionModel) getSelectionModel();
+        if (sm == null) {
+            return;
+        }
+        sm.direction = new Pair<>(rowDiff, columnDiff);
+
+        TableFocusModel fm = getFocusModel();
+        if (fm == null) {
+            return;
+        }
+
+        TablePositionBase focusedCell = getFocusedCell();
+        int currentRow = focusedCell.getRow();
+        int currentColumn = getVisibleLeafIndex(focusedCell.getTableColumn());
+
+        if (rowDiff < 0 && currentRow <= 0) return;
+        else if (rowDiff > 0 && currentRow >= getItemCount() - 1) return;
+        else if (columnDiff < 0 && currentColumn <= 0) return;
+        else if (columnDiff > 0 && currentColumn >= getVisibleLeafColumns().size() - 1) return;
+        else if (columnDiff > 0 && currentColumn == -1) return;
+
+        TableColumnBase tc = focusedCell.getTableColumn();
+        tc = getColumn(tc, columnDiff);
+
+        int row = focusedCell.getRow() + rowDiff;
+        
+        sm.clearAndSelect(row, tc);
+        setAnchor(row, tc);
+    }
+
+    private int findNextRow(TablePositionBase focusedCell, SpreadsheetCell cell) {
+        final ObservableList<ObservableList<SpreadsheetCell>> items = getControl().getItems();
+        final int itemCount = getItemCount();
+        SpreadsheetCell temp;
+        //If my cell is empty, I seek the next non-empty
+        if (isEmpty(cell)) {
+            for (int row = focusedCell.getRow() + 1; row < itemCount; ++row) {
+                temp = items.get(row).get(focusedCell.getColumn());
+                if (!isEmpty(temp)) {
+                    return row;
+                }
+            }
+        } else if (focusedCell.getRow() + 1 < itemCount && !isEmpty(items.get(focusedCell.getRow() + 1).get(focusedCell.getColumn()))) {
+            for (int row = focusedCell.getRow() + 2; row < getItemCount(); ++row) {
+                temp = items.get(row).get(focusedCell.getColumn());
+                if (isEmpty(temp)) {
+                    return row - 1;
+                }
+            }
+        } else {
+            for (int row = focusedCell.getRow() + 2; row < itemCount; ++row) {
+                temp = items.get(row).get(focusedCell.getColumn());
+                if (!isEmpty(temp)) {
+                    return row;
+                }
+            }
+        }
+        return itemCount - 1;
+    }
+
+    private void discontinuousSelectVertical(boolean previous) {
+        TableSelectionModel sm = getSelectionModel();
+        if (sm == null) {
+            return;
+        }
+
+        TableFocusModel fm = getFocusModel();
+        if (fm == null) {
+            return;
+        }
+        final TablePositionBase focusedCell = getFocusedCell();
+        if (focusedCell == null || focusedCell.getTableColumn() == null) {
+            return;
+        }
+
+        final SpreadsheetCell cell = getControl().getItems().get(fm.getFocusedIndex()).get(focusedCell.getColumn());
+
+        /**
+         * If the delta is >0, it means we want to go down, so we need to target
+         * the cell that is after our cell. So we need to take the last row of
+         * our cell if spanning. If the delta is < 0, it means we want to go up,
+         * so we just take the row.
+         */
+        int newRow = previous ? findPreviousRow(focusedCell, cell) : findNextRow(focusedCell, cell);;
+
+        // we don't let the newRow go outside the bounds of the data
+        newRow = Math.max(Math.min(getItemCount() - 1, newRow), 0);
+
+        final TablePositionBase<?> anchor = getAnchor();
+        int minRow = Math.min(anchor.getRow(), newRow);
+        int maxRow = Math.max(anchor.getRow(), newRow);
+        int minColumn = Math.min(anchor.getColumn(), focusedCell.getColumn());
+        int maxColumn = Math.max(anchor.getColumn(), focusedCell.getColumn());
+
+        sm.clearSelection();
+        if (minColumn != -1 && maxColumn != -1) {
+            sm.selectRange(minRow, getControl().getColumns().get(minColumn), maxRow,
+                    getControl().getColumns().get(maxColumn));
+        }
+        fm.focus(newRow, focusedCell.getTableColumn());
+        skin.focusScroll();
+    }
+
+    private void discontinuousSelectHorizontal(boolean previous) {
+        TableSelectionModel sm = getSelectionModel();
+        if (sm == null) {
+            return;
+        }
+
+        TableFocusModel fm = getFocusModel();
+        if (fm == null) {
+            return;
+        }
+        final TablePositionBase focusedCell = getFocusedCell();
+        if (focusedCell == null || focusedCell.getTableColumn() == null) {
+            return;
+        }
+
+        final int columnPos = getVisibleLeafIndex(focusedCell.getTableColumn());
+        int focusedCellRow = focusedCell.getRow();
+        final SpreadsheetCell cell = getControl().getItems().get(focusedCellRow).get(columnPos);
+
+        final int newColumn = previous ? findPreviousColumn(focusedCell, cell) : findNextColumn(focusedCell, cell);
+
+        final TablePositionBase<?> anchor = getAnchor();
+        int minRow = Math.min(anchor.getRow(), focusedCellRow);
+        int maxRow = Math.max(anchor.getRow(), focusedCellRow);
+        int minColumn = Math.min(anchor.getColumn(), newColumn);
+        int maxColumn = Math.max(anchor.getColumn(), newColumn);
+
+        sm.clearSelection();
+        if (minColumn != -1 && maxColumn != -1) {
+            sm.selectRange(minRow, getControl().getColumns().get(minColumn), maxRow,
+                    getControl().getColumns().get(maxColumn));
+        }
+        fm.focus(focusedCell.getRow(), getColumn(newColumn));
+        skin.focusScroll();
+    }
+
+    private int findNextColumn(TablePositionBase focusedCell, SpreadsheetCell cell) {
+        final ObservableList<ObservableList<SpreadsheetCell>> items = getControl().getItems();
+        final int itemCount = getControl().getColumns().size();
+        SpreadsheetCell temp;
+        //If my cell is empty, I seek the next non-empty
+        if (isEmpty(cell)) {
+            for (int column = focusedCell.getColumn() + 1; column < itemCount; ++column) {
+                temp = items.get(focusedCell.getRow()).get(column);
+                if (!isEmpty(temp)) {
+                    return column;
+                }
+            }
+        } else if (focusedCell.getColumn() + 1 < itemCount && !isEmpty(items.get(focusedCell.getRow()).get(focusedCell.getColumn() + 1))) {
+            for (int column = focusedCell.getColumn() + 2; column < itemCount; ++column) {
+                temp = items.get(focusedCell.getRow()).get(column);
+                if (isEmpty(temp)) {
+                    return column - 1;
+                }
+            }
+        } else {
+            for (int column = focusedCell.getColumn() + 2; column < itemCount; ++column) {
+                temp = items.get(focusedCell.getRow()).get(column);
+                if (!isEmpty(temp)) {
+                    return column;
+                }
+            }
+        }
+        return itemCount - 1;
+    }
+
+    private int findPreviousColumn(TablePositionBase focusedCell, SpreadsheetCell cell) {
+        final ObservableList<ObservableList<SpreadsheetCell>> items = getControl().getItems();
+        SpreadsheetCell temp;
+        //If my cell is empty, I seek the next non-empty
+        if (isEmpty(cell)) {
+            for (int column = focusedCell.getColumn() - 1; column >= 0; --column) {
+                temp = items.get(focusedCell.getRow()).get(column);
+                if (!isEmpty(temp)) {
+                    return column;
+                }
+            }
+        } else if (focusedCell.getColumn() - 1 >= 0 && !isEmpty(items.get(focusedCell.getRow()).get(focusedCell.getColumn() - 1))) {
+            for (int column = focusedCell.getColumn() - 2; column >= 0; --column) {
+                temp = items.get(focusedCell.getRow()).get(column);
+                if (isEmpty(temp)) {
+                    return column + 1;
+                }
+            }
+        } else {
+            for (int column = focusedCell.getColumn() - 2; column >= 0; --column) {
+                temp = items.get(focusedCell.getRow()).get(column);
+                if (!isEmpty(temp)) {
+                    return column;
+                }
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Cell is empty if there's nothing in it or if we have a NaN instead of a
+     * proper Double.
+     *
+     * @param cell
+     * @return
+     */
+    private boolean isEmpty(SpreadsheetCell cell) {
+        return cell.getGraphic() == null && (cell.getItem() == null
+                || (cell.getItem() instanceof Double && ((Double) cell.getItem()).isNaN()));
+    }
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/GridViewSkin.java b/src/impl/org/controlsfx/spreadsheet/GridViewSkin.java
new file mode 100644
index 0000000000000000000000000000000000000000..afb42b31ef850068f17cd23c988fbc5fdf26a151
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/GridViewSkin.java
@@ -0,0 +1,1138 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import java.lang.reflect.Field;
+import java.time.LocalDate;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.collections.ObservableMap;
+import javafx.collections.ObservableSet;
+import javafx.collections.SetChangeListener;
+import javafx.event.EventHandler;
+import javafx.geometry.HPos;
+import javafx.geometry.VPos;
+import javafx.scene.Node;
+import javafx.scene.control.IndexedCell;
+import javafx.scene.control.ResizeFeaturesBase;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumnBase;
+import javafx.scene.control.TableFocusModel;
+import javafx.scene.control.TablePositionBase;
+import javafx.scene.control.TableRow;
+import javafx.scene.control.TableSelectionModel;
+import javafx.scene.control.TableView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.Region;
+import javafx.stage.Screen;
+import javafx.util.Callback;
+
+import org.controlsfx.control.spreadsheet.Grid;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetColumn;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+import com.sun.javafx.scene.control.behavior.TableViewBehavior;
+import com.sun.javafx.scene.control.skin.TableHeaderRow;
+import com.sun.javafx.scene.control.skin.TableViewSkinBase;
+import com.sun.javafx.scene.control.skin.VirtualFlow;
+import javafx.application.Platform;
+import javafx.event.Event;
+import javafx.scene.control.ScrollBar;
+
+/**
+ * This skin is actually the skin of the SpreadsheetGridView (tableView)
+ * contained within the SpreadsheetView. The skin for the SpreadsheetView itself
+ * currently resides inside the SpreadsheetView constructor!
+ *
+ * We need to extends directly from TableViewSkinBase in order to work-around
+ * https://javafx-jira.kenai.com/browse/RT-34753 if we want to set a custom
+ * TableViewBehavior.
+ *
+ */
+public class GridViewSkin extends TableViewSkinBase<ObservableList<SpreadsheetCell>,ObservableList<SpreadsheetCell>,TableView<ObservableList<SpreadsheetCell>>,TableViewBehavior<ObservableList<SpreadsheetCell>>,TableRow<ObservableList<SpreadsheetCell>>,TableColumn<ObservableList<SpreadsheetCell>,?>> {
+        
+    /***************************************************************************
+     * * STATIC FIELDS * *
+     **************************************************************************/
+
+    /** Default height of a row. */
+    public static final double DEFAULT_CELL_HEIGHT;
+
+    // FIXME This should seriously be investigated ..
+    private static final double DATE_CELL_MIN_WIDTH = 200 - Screen.getPrimary().getDpi();
+
+    static {
+        double cell_size = 24.0;
+        try {
+            Class<?> clazz = com.sun.javafx.scene.control.skin.CellSkinBase.class;
+            Field f = clazz.getDeclaredField("DEFAULT_CELL_SIZE"); //$NON-NLS-1$
+            f.setAccessible(true);
+            cell_size = f.getDouble(null);
+        } catch (NoSuchFieldException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (SecurityException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IllegalArgumentException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        DEFAULT_CELL_HEIGHT = cell_size;
+    }
+
+    /**
+     * When we add some tableCell to some topRow in order for them to be on top
+     * in term of z-order. We may end up with the situation where the row that
+     * put the cell is not in the ViewPort anymore. For example when a fixedRow
+     * has taken over the real row when scrolling down. Then, the tableCell
+     * added is still hanging out in the topRow. That tableCell has no clue that
+     * its "creator" has been destroyed or re-used since that tableCell was not
+     * technically belonging to its "creator". Therefore, we need to track those
+     * cells in order to remove them each time.
+     */
+    final Map<GridRow,Set<CellView>> deportedCells = new HashMap<>();
+    /***************************************************************************
+     * * PRIVATE FIELDS * *
+     **************************************************************************/
+    /**
+     * When resizing, we save the height here in order to override default row
+     * height. package protected.
+     */
+    ObservableMap<Integer, Double> rowHeightMap = FXCollections.observableHashMap();
+
+    /** The editor. */
+    private GridCellEditor gridCellEditor;
+
+    protected final SpreadsheetHandle handle;
+    protected SpreadsheetView spreadsheetView;
+    protected VerticalHeader verticalHeader;
+    protected HorizontalPicker horizontalPickers;
+    
+    /**
+     * The currently fixedRow. This handles an Integer's set of rows being
+     * fixed. NOT Fixable but truly fixed.
+     */
+    private ObservableSet<Integer> currentlyFixedRow = FXCollections.observableSet(new HashSet<Integer>());
+
+    /**
+     * A list of Integer with the current selected Rows. This is useful for
+     * HorizontalHeader and VerticalHeader because they need to highlight when a
+     * selection is made.
+     */
+    private final ObservableList<Integer> selectedRows = FXCollections.observableArrayList();
+
+    /**
+     * A list of Integer with the current selected Columns. This is useful for
+     * HorizontalHeader and VerticalHeader because they need to highlight when a
+     * selection is made.
+     */
+    private final ObservableList<Integer> selectedColumns = FXCollections.observableArrayList();
+
+    /**
+     * The total height of the currently fixedRows.
+     */
+    private double fixedRowHeight = 0;
+
+    /**
+     * These variable try to optimize the layout of the rows in order not to layout
+     * every time every row.
+     * 
+     * So rowToLayout contains the rows that really needs layout(contain span or fixed).
+     * 
+     * And hBarValue is an indicator for the VirtualFlow. When the Hbar is touched, this BitSet
+     * is set to false. And when a row is drawing, it flips its value in this BitSet. 
+     * So that we know when scrolling up or down whether a row has taken into account
+     * that the HBar was moved (otherwise, blank area may appear).
+     */
+    BitSet hBarValue;
+    BitSet rowToLayout;
+    
+    /**
+     * This rectangle will be used for drawing a border around the selection.
+     */
+    RectangleSelection rectangleSelection;
+    
+    /**
+     * This is the current width used by the currently fixed column on the left. 
+     */
+    double fixedColumnWidth;
+    
+    /**
+     * When we try to select cells after a setGrid, we end up with the cell
+     * selected but no visual confirmation. In order to prevent that, we need to
+     * warn the selectionModel when the layout is starting and then the
+     * selectionModel will do the appropriate actions in order to force the
+     * visual to come.
+     */
+    BooleanProperty lastRowLayout = new SimpleBooleanProperty(true);
+    
+    /***************************************************************************
+     * * CONSTRUCTOR * *
+     **************************************************************************/
+    public GridViewSkin(final SpreadsheetHandle handle) { 
+        super(handle.getGridView(), new GridViewBehavior(handle.getGridView()));
+        super.init(handle.getGridView());
+        
+        this.handle = handle;
+        this.spreadsheetView = handle.getView();
+        gridCellEditor = new GridCellEditor(handle);
+        TableView<ObservableList<SpreadsheetCell>> tableView = handle.getGridView();
+
+        //Set a new row factory, useful when handling row height.
+        tableView.setRowFactory(new Callback<TableView<ObservableList<SpreadsheetCell>>, TableRow<ObservableList<SpreadsheetCell>>>() {
+            @Override
+            public TableRow<ObservableList<SpreadsheetCell>> call(TableView<ObservableList<SpreadsheetCell>> p) {
+                return new GridRow(handle);
+            }
+        });
+
+        tableView.getStyleClass().add("cell-spreadsheet"); //$NON-NLS-1$
+
+        getCurrentlyFixedRow().addListener(currentlyFixedRowListener);
+        spreadsheetView.getFixedRows().addListener(fixedRowsListener);
+        spreadsheetView.getFixedColumns().addListener(fixedColumnsListener);
+
+        init();
+        /**
+         * When we are changing the grid we re-instantiate the rowToLayout because
+         * spans and fixedRow may have changed.
+         */
+        handle.getView().gridProperty().addListener(new ChangeListener<Grid>() {
+
+            @Override
+            public void changed(ObservableValue<? extends Grid> ov, Grid t, Grid t1) {
+                 rowToLayout = initRowToLayoutBitSet();
+            }
+        });
+        hBarValue = new BitSet(handle.getView().getGrid().getRowCount());
+        rowToLayout = initRowToLayoutBitSet();
+        // Because fixedRow Listener is not reacting first time.
+        computeFixedRowHeight();
+        
+        
+        EventHandler<MouseEvent> ml = (MouseEvent event) -> {
+            // RT-15127: cancel editing on scroll. This is a bit extreme
+            // (we are cancelling editing on touching the scrollbars).
+            // This can be improved at a later date.
+            if (tableView.getEditingCell() != null) {
+                tableView.edit(-1, null); 
+            }
+            
+            // This ensures that the table maintains the focus, even when the vbar
+            // and hbar controls inside the flow are clicked. Without this, the
+            // focus border will not be shown when the user interacts with the
+            // scrollbars, and more importantly, keyboard navigation won't be
+            // available to the user.
+            tableView.requestFocus();
+        };
+        
+        getFlow().getVerticalBar().addEventFilter(MouseEvent.MOUSE_PRESSED, ml);
+        getFlow().getHorizontalBar().addEventFilter(MouseEvent.MOUSE_PRESSED, ml);
+
+        // init the behavior 'closures'
+        TableViewBehavior<ObservableList<SpreadsheetCell>> behavior = getBehavior();
+        behavior.setOnFocusPreviousRow(new Runnable() {
+            @Override public void run() { onFocusPreviousCell(); }
+        });
+        behavior.setOnFocusNextRow(new Runnable() {
+            @Override public void run() { onFocusNextCell(); }
+        });
+        behavior.setOnMoveToFirstCell(new Runnable() {
+            @Override public void run() { onMoveToFirstCell(); }
+        });
+        behavior.setOnMoveToLastCell(new Runnable() {
+            @Override public void run() { onMoveToLastCell(); }
+        });
+        behavior.setOnScrollPageDown(new Callback<Boolean, Integer>() {
+            @Override public Integer call(Boolean isFocusDriven) { return onScrollPageDown(isFocusDriven); }
+        });
+        behavior.setOnScrollPageUp(new Callback<Boolean, Integer>() {
+            @Override public Integer call(Boolean isFocusDriven) { return onScrollPageUp(isFocusDriven); }
+        });
+        behavior.setOnSelectPreviousRow(new Runnable() {
+            @Override public void run() { onSelectPreviousCell(); }
+        });
+        behavior.setOnSelectNextRow(new Runnable() {
+            @Override public void run() { onSelectNextCell(); }
+        });
+        behavior.setOnSelectLeftCell(new Runnable() {
+            @Override public void run() { onSelectLeftCell(); }
+        });
+        behavior.setOnSelectRightCell(new Runnable() {
+            @Override public void run() { onSelectRightCell(); }
+        });
+
+        registerChangeListener(tableView.fixedCellSizeProperty(), "FIXED_CELL_SIZE");
+
+    }  
+
+    /**
+     * Compute the height of a particular row. If the row is in
+     * {@link Grid#AUTOFIT}, {@link #DEFAULT_CELL_HEIGHT} is returned.
+     *
+     * @param row
+     * @return
+     */
+    public double getRowHeight(int row) {
+        Double rowHeightCache = rowHeightMap.get(row);
+        if (rowHeightCache == null) {
+            double rowHeight = handle.getView().getGrid().getRowHeight(row);
+            return rowHeight == Grid.AUTOFIT ? DEFAULT_CELL_HEIGHT : rowHeight;
+        } else {
+            return rowHeightCache;
+        }
+    }
+
+    public double getFixedRowHeight() {
+        return fixedRowHeight;
+    }
+
+    public ObservableList<Integer> getSelectedRows() {
+        return selectedRows;
+    }
+
+    public ObservableList<Integer> getSelectedColumns() {
+        return selectedColumns;
+    }
+
+    public GridCellEditor getSpreadsheetCellEditorImpl() {
+        return gridCellEditor;
+    }
+
+    /**
+     * This return the GridRow which has the specified index if found. Otherwise
+     * null is returned.
+     *
+     * @param index
+     * @return
+     */
+    public GridRow getRowIndexed(int index) {
+        List<? extends IndexedCell> cells = getFlow().getCells();
+        if (!cells.isEmpty()) {
+            IndexedCell cell = cells.get(0);
+            if (index >= cell.getIndex() && index - cell.getIndex() < cells.size()) {
+                return (GridRow) cells.get(index - cell.getIndex());
+            }
+        }
+        for (IndexedCell cell : getFlow().getFixedCells()) {
+            if (cell.getIndex() == index) {
+                return (GridRow) cell;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * This return the row at the specified index in the list. The index
+     * specified HAS NOTHING to do with the index of the row.
+     * @see #getRowIndexed(int) for a getting a row with its real index.
+     * @param index
+     * @return
+     */
+    public GridRow getRow(int index) {
+        return (GridRow) getFlow().getCells().get(index);
+    }
+
+    /**
+     * Indicate whether or not the row at the specified index is currently being
+     * displayed.
+     * 
+     * @param index
+     * @return
+     */
+    public final boolean containsRow(int index) {
+        for (Object obj : getFlow().getCells()) {
+            if (((GridRow) obj).getIndex() == index)
+                return true;
+        }
+        return false;
+    }
+
+    public int getCellsSize() {
+        return getFlow().getCells().size();
+    }
+
+    public ScrollBar getHBar() {
+        if (getFlow() != null) {
+            return getFlow().getHorizontalBar();
+        }
+        return null;
+    }
+
+    public ScrollBar getVBar() {
+        return getFlow().getVerticalBar();
+    }
+
+    /**
+     * Will compute for every row the necessary height and fit the line.
+     * This can degrade performance a lot so need to use it wisely. 
+     * But I don't see other solutions right now.
+     */
+    public void resizeRowsToFitContent() {
+        Grid grid = spreadsheetView.getGrid();
+        int maxRows = handle.getView().getGrid().getRowCount();
+        for (int row = 0; row < maxRows; row++) {
+            if (grid.isRowResizable(row)) {
+                resizeRowToFitContent(row);
+            }
+        }
+    }
+    
+    /**
+     * Will compute for the row the necessary height and fit the line.
+     * This can degrade performance a lot so need to use it wisely. 
+     * But I don't see other solutions right now.
+     * @param row
+     */
+    public void resizeRowToFitContent(int row) {
+        if(getSkinnable().getColumns().isEmpty()){
+            return;
+        }
+        final TableColumn<ObservableList<SpreadsheetCell>, ?> col = getSkinnable().getColumns().get(0);
+        List<?> items = itemsProperty().get();
+        if (items == null || items.isEmpty()) {
+            return;
+        }
+        
+        if (!spreadsheetView.getGrid().isRowResizable(row)) {
+            return;
+        }
+        Callback/* <TableColumn<T, ?>, TableCell<T,?>> */ cellFactory = col.getCellFactory();
+        if (cellFactory == null) {
+            return;
+        }
+
+        CellView cell = (CellView) cellFactory.call(col);
+        if (cell == null) {
+            return;
+        }
+
+        // set this property to tell the TableCell we want to know its actual
+        // preferred width, not the width of the associated TableColumnBase
+        cell.getProperties().put("deferToParentPrefWidth", Boolean.TRUE); //$NON-NLS-1$
+        
+        // determine cell padding
+        double padding = 5;
+
+        Node n = cell.getSkin() == null ? null : cell.getSkin().getNode();
+        if (n instanceof Region) {
+            Region r = (Region) n;
+            padding = r.snappedTopInset() + r.snappedBottomInset();
+        }
+
+        double maxHeight;
+        maxHeight = 0;
+        getChildren().add(cell);
+
+        for (TableColumn column : getSkinnable().getColumns()) {
+            cell.updateTableColumn(column);
+            cell.updateTableView(handle.getGridView());
+            cell.updateIndex(row);
+
+            if ((cell.getText() != null && !cell.getText().isEmpty()) || cell.getGraphic() != null) {
+                cell.setWrapText(true);
+
+                cell.impl_processCSS(false);
+                maxHeight = Math.max(maxHeight, cell.prefHeight(column.getWidth()));
+            }
+        }
+        getChildren().remove(cell);
+        rowHeightMap.put(row, maxHeight + padding);
+        Event.fireEvent(spreadsheetView, new SpreadsheetView.RowHeightEvent(row, maxHeight + padding));
+
+        rectangleSelection.updateRectangle();
+    }
+    
+    public void resizeRowsToMaximum() {
+        //First we resize to fit.
+        resizeRowsToFitContent();
+        
+        Grid grid = spreadsheetView.getGrid();
+        
+        //Then we take the maximum and apply it everywhere.
+        double maxHeight = 0;
+        for(int key:rowHeightMap.keySet()){
+            maxHeight = Math.max(maxHeight, rowHeightMap.get(key));
+        }
+        
+        rowHeightMap.clear();
+        int maxRows = handle.getView().getGrid().getRowCount();
+        for (int row = 0; row < maxRows; row++) {
+            if (grid.isRowResizable(row)) {
+                Event.fireEvent(spreadsheetView, new SpreadsheetView.RowHeightEvent(row, maxHeight));
+                rowHeightMap.put(row, maxHeight);
+            }
+        }
+        rectangleSelection.updateRectangle();
+    }
+    
+    public void resizeRowsToDefault() {
+        rowHeightMap.clear();
+        Grid grid = spreadsheetView.getGrid();
+        /**
+         * When resizing to default, we need to go through the visible rows in
+         * order to update them directly. Because if the rowHeightMap is empty,
+         * the rows will not detect that maybe the height has changed.
+         */
+        for (GridRow row : (List<GridRow>) getFlow().getCells()) {
+            if (grid.isRowResizable(row.getIndex())) {
+                double newHeight = row.computePrefHeight(-1);
+                if (row.getPrefHeight() != newHeight) {
+                    row.setRowHeight(newHeight);
+                    row.requestLayout();
+                }
+            }
+        }
+
+        //Fixing https://bitbucket.org/controlsfx/controlsfx/issue/358/
+        getFlow().layoutChildren();
+
+        for (GridRow row : (List<GridRow>) getFlow().getCells()) {
+            double height = getRowHeight(row.getIndex());
+            if (row.getHeight() != height) {
+                if (grid.isRowResizable(row.getIndex())) {
+                    row.setRowHeight(height);
+                }
+            }
+        }
+        rectangleSelection.updateRectangle();
+    }
+    /**
+     * We want to have extra space when displaying LocalDate because they will
+     * use an editor that display a little icon on the right. Thus, that icon is
+     * reducing the visibility of the date string.
+     */
+    @Override
+    public void resizeColumnToFitContent(TableColumn<ObservableList<SpreadsheetCell>, ?> tc, int maxRows) {
+        
+        final TableColumn<ObservableList<SpreadsheetCell>, ?> col = tc;
+        List<?> items = itemsProperty().get();
+        if (items == null || items.isEmpty()) {
+            return;
+        }
+
+        Callback/* <TableColumn<T, ?>, TableCell<T,?>> */ cellFactory = col.getCellFactory();
+        if (cellFactory == null) {
+            return;
+        }
+
+        TableCell<ObservableList<SpreadsheetCell>, ?> cell = (TableCell<ObservableList<SpreadsheetCell>, ?>) cellFactory
+                .call(col);
+        if (cell == null) {
+            return;
+        }
+
+        //The current index of that column
+        int indexColumn = handle.getGridView().getColumns().indexOf(tc);
+        
+        /**
+         * This is to prevent resize of columns that have the same default width
+         * at initialisation. If the "system" is calling this method, the
+         * maxRows will be set at 30. When we set a prefWidth and it's equal to
+         * the "default width", the system wants to resize the column. We must
+         * prevent that, thus we check if the two conditions are met.
+         */
+        if(maxRows == 30 && handle.isColumnWidthSet(indexColumn)){
+            return;
+        }
+        
+        // set this property to tell the TableCell we want to know its actual
+        // preferred width, not the width of the associated TableColumnBase
+        cell.getProperties().put("deferToParentPrefWidth", Boolean.TRUE); //$NON-NLS-1$
+        
+        // determine cell padding
+        double padding = 10;
+        Node n = cell.getSkin() == null ? null : cell.getSkin().getNode();
+        if (n instanceof Region) {
+            Region r = (Region) n;
+            padding = r.snappedLeftInset() + r.snappedRightInset();
+        }
+
+        ObservableList<ObservableList<SpreadsheetCell>> gridRows = spreadsheetView.getGrid().getRows();//.get(row)
+        
+        /**
+         * If maxRows is -1, we take all rows. If it's 30, it means it's coming
+         * from TableColumnHeader during initialization, so we push it to 100.
+         */
+        int rows = maxRows == -1 ? items.size() : Math.min(items.size(), maxRows == 30 ? 100 : maxRows);
+        double maxWidth = 0;
+        boolean datePresent = false;
+        cell.updateTableColumn(col);
+        cell.updateTableView(handle.getGridView());
+        /**
+         * Sometime the skin is not set, and the width computed is zero which
+         * destroy the grid... So in that case, we manually set the skin...
+         */
+        if (cell.getSkin() == null) {
+            cell.setSkin(new CellViewSkin((TableCell<ObservableList<SpreadsheetCell>, SpreadsheetCell>) cell));
+        }
+        for (int row = 0; row < rows; row++) {
+            cell.updateIndex(row);
+            
+            if ((cell.getText() != null && !cell.getText().isEmpty()) || cell.getGraphic() != null) {
+                getChildren().add(cell);
+
+                if (((SpreadsheetCell) cell.getItem()).getItem() instanceof LocalDate) {
+                    datePresent = true;
+                }
+                cell.impl_processCSS(false);
+                double width = cell.prefWidth(-1);
+                /**
+                 * If the cell is spanning in column, we need to take the other
+                 * columns into account in the calculation of the width. So we
+                 * compute the width needed by the cell and we substract the
+                 * other columns width.
+                 *
+                 * Also if the cell considered is not in the column, we still
+                 * have to compute because a previous column may have based its
+                 * calculation on the current width which will be modified.
+                 */
+                SpreadsheetCell spc = gridRows.get(row).get(indexColumn);
+                if (spc.getColumnSpan() > 1) {
+                    for (int i = spc.getColumn(); i < spc.getColumn() + spc.getColumnSpan(); ++i) {
+                        if(i != indexColumn){
+                            width -= spreadsheetView.getColumns().get(i).getWidth();
+                        }
+                    }
+                }
+                maxWidth = Math.max(maxWidth, width);
+                getChildren().remove(cell);
+            }
+        }
+
+        // dispose of the cell to prevent it retaining listeners (see RT-31015)
+        cell.updateIndex(-1);
+
+        // RT-23486
+        double widthMax = maxWidth + padding;
+        if (handle.getGridView().getColumnResizePolicy() == TableView.CONSTRAINED_RESIZE_POLICY) {
+            widthMax = Math.max(widthMax, col.getWidth());
+        }
+
+        if (datePresent && widthMax < DATE_CELL_MIN_WIDTH) {
+            widthMax = DATE_CELL_MIN_WIDTH;
+        }
+        /**
+         * This method is called by the system at initialisation and later by
+         * some methods that check wether the specified column is resizable. So
+         * we do not check if the column is resizable because it will be checked
+         * before. If we end up here, it either means the column is resizable,
+         * OR this is the initialisation and we haven't set a specific width so
+         * we just compute one time the correct width for that column, and once
+         * set, it will not be called again.
+         *
+         * Also, if the prefWidth has already been set but the user resized the
+         * column with his mouse, we must force the column to resize because
+         * setting the prefWidth again will not trigger the listeners.
+         */
+        widthMax = snapSize(widthMax);
+        if (col.getPrefWidth() == widthMax && col.getWidth() != widthMax) {
+            col.impl_setWidth(widthMax);
+        } else {
+            col.setPrefWidth(widthMax);
+        }
+        
+        rectangleSelection.updateRectangle();
+    }
+
+    /***************************************************************************
+     * * PRIVATE/PROTECTED METHOD * *
+     **************************************************************************/
+    protected final void init() {
+        rectangleSelection = new RectangleSelection(this, (TableViewSpanSelectionModel) handle.getGridView().getSelectionModel());
+        getFlow().getVerticalBar().valueProperty().addListener(vbarValueListener);
+        verticalHeader = new VerticalHeader(handle);
+        getChildren().add(verticalHeader);
+
+        ((HorizontalHeader) getTableHeaderRow()).init();
+        verticalHeader.init(this, (HorizontalHeader) getTableHeaderRow());
+        
+        horizontalPickers = new HorizontalPicker((HorizontalHeader) getTableHeaderRow(), spreadsheetView);
+        getChildren().add(horizontalPickers);
+        getFlow().init(spreadsheetView);
+        ((GridViewBehavior)getBehavior()).setGridViewSkin(this);
+    }
+
+    protected final ObservableSet<Integer> getCurrentlyFixedRow() {
+        return currentlyFixedRow;
+    }
+
+    /**
+     * Used in the HorizontalColumnHeader when we need to resize in double
+     * click.
+     * 
+     * @param tc
+     * @param maxRows
+     */
+    public void resize(TableColumnBase<?, ?> tc, int maxRows) {
+        if(tc.isResizable()){
+            int columnIndex = getColumns().indexOf(tc);
+            TableColumn tableColumn = getColumns().get(columnIndex);
+            resizeColumnToFitContent(tableColumn, maxRows);
+            Event.fireEvent(spreadsheetView, new SpreadsheetView.ColumnWidthEvent(columnIndex, tableColumn.getWidth()));
+        }
+    }
+
+    @Override
+    protected void layoutChildren(double x, double y, double w, final double h) {
+        if (spreadsheetView == null) {
+            return;
+        }
+        double verticalHeaderWidth = verticalHeader.computeHeaderWidth();
+        double horizontalPickerHeight = spreadsheetView.getColumnPickers().isEmpty() ? 0: VerticalHeader.PICKER_SIZE;
+        
+        if (spreadsheetView.isShowRowHeader() || !spreadsheetView.getRowPickers().isEmpty()) {
+            x += verticalHeaderWidth;
+            w -= verticalHeaderWidth;
+        } else {
+            x = 0.0;
+        }
+
+        
+        y += horizontalPickerHeight;
+        super.layoutChildren(x, y, w, h-horizontalPickerHeight);
+
+        final double baselineOffset = getSkinnable().getLayoutBounds().getHeight() / 2;
+        double tableHeaderRowHeight = 0;
+
+        if(!spreadsheetView.getColumnPickers().isEmpty()){
+            layoutInArea(horizontalPickers, x, y - VerticalHeader.PICKER_SIZE, w, tableHeaderRowHeight, baselineOffset, HPos.CENTER, VPos.CENTER);
+        }
+        
+        if (spreadsheetView.showColumnHeaderProperty().get()) {
+            // position the table header
+            tableHeaderRowHeight = getTableHeaderRow().prefHeight(-1);
+            layoutInArea(getTableHeaderRow(), x, y, w, tableHeaderRowHeight, baselineOffset, HPos.CENTER, VPos.CENTER);
+
+            y += tableHeaderRowHeight;
+        } else {
+            // This is temporary handled in the HorizontalHeader with Css
+            // FIXME tweak open in https://javafx-jira.kenai.com/browse/RT-32673
+        }
+
+        if (spreadsheetView.isShowRowHeader() || !spreadsheetView.getRowPickers().isEmpty()) {
+            layoutInArea(verticalHeader, x - verticalHeaderWidth, y - tableHeaderRowHeight, w, h, baselineOffset,
+                    HPos.CENTER, VPos.CENTER);
+        }
+    }
+
+    @Override
+    protected void onFocusPreviousCell() {
+        focusScroll();
+    }
+
+    @Override
+    protected void onFocusNextCell() {
+        focusScroll();
+    }
+
+    void focusScroll() {
+        final TableFocusModel<?, ?> fm = getFocusModel();
+        if (fm == null) {
+            return;
+        }
+        /**
+         * ***************************************************************
+         * MODIFIED
+         ****************************************************************
+         */
+        final int row = fm.getFocusedIndex();
+        // We try to make visible the rows that may be hidden by Fixed rows
+        if (!getFlow().getCells().isEmpty()
+                && getFlow().getCells().get(spreadsheetView.getFixedRows().size()).getIndex() > row
+                && !spreadsheetView.getFixedRows().contains(row)) {
+            flow.scrollTo(row);
+        } else {
+            flow.show(row);
+        }
+        scrollHorizontally();
+        /**
+         * ***************************************************************
+         * END OF MODIFIED
+         ****************************************************************
+         */
+    }
+    
+    @Override
+    protected void onSelectPreviousCell() {
+        super.onSelectPreviousCell();
+        scrollHorizontally();
+    }
+
+    @Override
+    protected void onSelectNextCell() {
+        super.onSelectNextCell();
+        scrollHorizontally();
+    }
+
+    @Override
+    protected VirtualFlow<TableRow<ObservableList<SpreadsheetCell>>> createVirtualFlow() {
+        return new GridVirtualFlow<>(this);
+    }
+
+    @Override
+    protected TableHeaderRow createTableHeaderRow() {
+        return new HorizontalHeader(this);
+    }
+    
+    protected HorizontalHeader getHorizontalHeader(){
+        return (HorizontalHeader) getTableHeaderRow();
+    }
+
+    BooleanProperty getTableMenuButtonVisibleProperty() {
+        return tableMenuButtonVisibleProperty();
+    }
+
+    @Override
+    public void scrollHorizontally(){
+        super.scrollHorizontally();
+    }
+    
+    @Override
+    protected void scrollHorizontally(TableColumn<ObservableList<SpreadsheetCell>, ?> col) {
+        if (col == null || !col.isVisible()) {
+            return;
+        }
+        /**
+         * We modified this function so that we ensure that any selected cells
+         * will not be below a fixed column. Because when there's some fixed
+         * columns, the "left border" is not the table anymore, but the right
+         * side of the last fixed columns.
+         *
+         * Moreover, we need to re-compute the fixedColumnWidth because the
+         * layout of the rows hasn't been done yet and the value is not right.
+         * So we might end up below a fixedColumns.
+         */
+        
+        fixedColumnWidth = 0;
+        final double pos = getFlow().getHorizontalBar().getValue();
+        int index = getColumns().indexOf(col);
+        double start = 0;// scrollX;
+
+        for (int i = 0; i < index; ++i) {
+            SpreadsheetColumn column = spreadsheetView.getColumns().get(i);
+            if (column.isFixed()) {
+                fixedColumnWidth += column.getWidth();
+            }
+            start += column.getWidth();
+        }
+
+        final double end = start + col.getWidth();
+
+        // determine the visible width of the table
+        final double headerWidth = handle.getView().getWidth() - snappedLeftInset() - snappedRightInset() - verticalHeader.getVerticalHeaderWidth();
+
+        // determine by how much we need to translate the table to ensure that
+        // the start position of this column lines up with the left edge of the
+        // tableview, and also that the columns don't become detached from the
+        // right edge of the table
+        final double max = getFlow().getHorizontalBar().getMax();
+        double newPos;
+
+        /**
+         * If the starting position of our column if inferior to the left egde
+         * (of tableView or fixed columns), then we need to scroll.
+         */
+        if (start < pos + fixedColumnWidth && start >= 0 && start >= fixedColumnWidth) {
+            newPos = start - fixedColumnWidth < 0 ? start : start - fixedColumnWidth;
+            getFlow().getHorizontalBar().setValue(newPos);
+        //If the starting point is not visible on the right.    
+        } else if(start > pos + headerWidth){
+            final double delta = start < 0 || end > headerWidth ? start - pos - fixedColumnWidth : 0;
+            newPos = pos + delta > max ? max : pos + delta;
+            getFlow().getHorizontalBar().setValue(newPos);
+        }
+        /**
+         * In all other cases, it means the cell is visible so no scroll needed,
+         * because otherwise we may end up with a continous scroll that always
+         * place the selected cell in the center of the screen.
+         */
+    }
+
+    private void verticalScroll() {
+        verticalHeader.requestLayout();
+    }
+
+    GridVirtualFlow<?> getFlow() {
+        return (GridVirtualFlow<?>) flow;
+    }
+
+    /**
+     * Return a BitSet of the rows that needs layout all the time. This
+     * includes any row containing a span, or a fixed row.
+     * @return 
+     */
+    private BitSet initRowToLayoutBitSet(){
+        Grid grid =  handle.getView().getGrid();
+        BitSet bitSet = new BitSet(grid.getRowCount());
+        for(int row = 0;row<grid.getRowCount();++row){
+            if(spreadsheetView.getFixedRows().contains(row)){
+                bitSet.set(row);
+                continue;
+            }
+            List<SpreadsheetCell> myRow = grid.getRows().get(row);
+            for(SpreadsheetCell cell:myRow){
+                
+                if(cell.getRowSpan()>1 /*|| cell.getColumnSpan() >1*/){
+                    bitSet.set(row);
+                    break;
+                }
+            }
+        }
+        return bitSet;
+    }
+    
+    /**
+     * When the vertical moves, we update the verticalHeader
+     */
+    private final InvalidationListener vbarValueListener = new InvalidationListener() {
+        @Override
+        public void invalidated(Observable valueModel) {
+            verticalScroll();
+        }
+    };
+
+    /**
+     * We listen on the FixedRows in order to do the modification in the
+     * VirtualFlow
+     */
+    private final ListChangeListener<Integer> fixedRowsListener = new ListChangeListener<Integer>() {
+        @Override
+        public void onChanged(Change<? extends Integer> c) {
+            hBarValue.clear();
+            while (c.next()) {
+                if (c.wasPermutated()) {
+                    for (Integer fixedRow : c.getList()) {
+                        rowToLayout.set(fixedRow, true);
+                    }
+                } else {
+                    for (Integer unfixedRow : c.getRemoved()) {
+                        rowToLayout.set(unfixedRow, false);
+                    //If the grid permits it, we check the spanning in order not
+                        //to remove a row that might need layout.
+                        if (spreadsheetView.getGrid().getRows().size() > unfixedRow) {
+                            List<SpreadsheetCell> myRow = spreadsheetView.getGrid().getRows().get(unfixedRow);
+                            for (SpreadsheetCell cell : myRow) {
+                                if (cell.getRowSpan() > 1 || cell.getColumnSpan() > 1) {
+                                    rowToLayout.set(unfixedRow, true);
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    //We check for the newly fixedRow
+                    for (Integer fixedRow : c.getAddedSubList()) {
+                        rowToLayout.set(fixedRow, true);
+                    }
+                }
+            }
+            // requestLayout() not responding immediately..
+            getFlow().requestLayout();
+        }
+    };
+
+    /**
+     * We listen on the currentlyFixedRow in order to do the modification in the
+     * FixedRowHeight.
+     */
+    private final SetChangeListener<? super Integer> currentlyFixedRowListener = new SetChangeListener<Integer>() {
+        @Override
+        public void onChanged(javafx.collections.SetChangeListener.Change<? extends Integer> arg0) {
+            computeFixedRowHeight();
+        }
+    };
+
+    /**
+     * We compute the total height of the fixedRows so that the selection can
+     * use it without performance regression.
+     */
+    public void computeFixedRowHeight() {
+        fixedRowHeight = 0;
+        for (int i : getCurrentlyFixedRow()) {
+            fixedRowHeight += getRowHeight(i);
+        }
+    }
+
+    /**
+     * We listen on the FixedColumns in order to do the modification in the
+     * VirtualFlow.
+     */
+    private final ListChangeListener<SpreadsheetColumn> fixedColumnsListener = new ListChangeListener<SpreadsheetColumn>() {
+        @Override
+        public void onChanged(Change<? extends SpreadsheetColumn> c) {
+            hBarValue.clear();
+            getFlow().requestLayout();
+            // requestLayout() not responding immediately..
+//            getFlow().layoutTotal();
+        }
+    };
+
+    @Override
+    protected TableSelectionModel<ObservableList<SpreadsheetCell>> getSelectionModel() {
+        return getSkinnable().getSelectionModel();
+    }
+
+    @Override
+    protected TableFocusModel<ObservableList<SpreadsheetCell>, TableColumn<ObservableList<SpreadsheetCell>, ?>> getFocusModel() {
+        return getSkinnable().getFocusModel();
+    }
+
+    @Override
+    protected TablePositionBase<? extends TableColumn<ObservableList<SpreadsheetCell>, ?>> getFocusedCell() {
+        return getSkinnable().getFocusModel().getFocusedCell();
+    }
+
+    @Override
+    protected ObservableList<? extends TableColumn<ObservableList<SpreadsheetCell>, ?>> getVisibleLeafColumns() {
+        return getSkinnable().getVisibleLeafColumns();
+    }
+
+    @Override
+    protected int getVisibleLeafIndex(TableColumn<ObservableList<SpreadsheetCell>, ?> tc) {
+        return getSkinnable().getVisibleLeafIndex(tc);
+    }
+
+    @Override
+    protected TableColumn<ObservableList<SpreadsheetCell>, ?> getVisibleLeafColumn(int col) {
+        return getSkinnable().getVisibleLeafColumn(col);
+    }
+
+    @Override
+    protected ObservableList<TableColumn<ObservableList<SpreadsheetCell>, ?>> getColumns() {
+        return getSkinnable().getColumns();
+    }
+
+    @Override
+    protected ObservableList<TableColumn<ObservableList<SpreadsheetCell>, ?>> getSortOrder() {
+        return getSkinnable().getSortOrder();
+    }
+
+    @Override
+    protected ObjectProperty<ObservableList<ObservableList<SpreadsheetCell>>> itemsProperty() {
+        return getSkinnable().itemsProperty();
+    }
+
+    @Override
+    protected ObjectProperty<Callback<TableView<ObservableList<SpreadsheetCell>>, TableRow<ObservableList<SpreadsheetCell>>>> rowFactoryProperty() {
+        return getSkinnable().rowFactoryProperty();
+    }
+
+    @Override
+    protected ObjectProperty<Node> placeholderProperty() {
+        return getSkinnable().placeholderProperty();
+    }
+
+    @Override
+    protected BooleanProperty tableMenuButtonVisibleProperty() {
+        return getSkinnable().tableMenuButtonVisibleProperty();
+    }
+
+    @Override
+    protected ObjectProperty<Callback<ResizeFeaturesBase, Boolean>> columnResizePolicyProperty() {
+        return (ObjectProperty<Callback<ResizeFeaturesBase, Boolean>>) (Object)getSkinnable().columnResizePolicyProperty();
+    }
+
+    @Override
+    protected boolean resizeColumn(TableColumn<ObservableList<SpreadsheetCell>, ?> tc, double delta) {
+        getHorizontalHeader().getRootHeader().lastColumnResized = getColumns().indexOf(tc);
+        boolean returnedValue = getSkinnable().resizeColumn(tc, delta);
+        if(returnedValue){
+            Event.fireEvent(spreadsheetView, new SpreadsheetView.ColumnWidthEvent(getColumns().indexOf(tc), tc.getWidth()));
+        }
+        return returnedValue;
+    }
+
+    @Override
+    protected void edit(int index, TableColumn<ObservableList<SpreadsheetCell>, ?> column) {
+        getSkinnable().edit(index, column);
+    }
+
+    @Override
+    public TableRow<ObservableList<SpreadsheetCell>> createCell() {
+        TableRow<ObservableList<SpreadsheetCell>> cell;
+
+        if (getSkinnable().getRowFactory() != null) {
+            cell = getSkinnable().getRowFactory().call(getSkinnable());
+        } else {
+            cell = new TableRow<>();
+        }
+
+        cell.updateTableView(getSkinnable());
+        return cell;
+    }
+
+    @Override
+    public int getItemCount() {
+        return getSkinnable().getItems() == null ? 0 : getSkinnable().getItems().size();
+    }
+
+    /**
+     * If the scene is not yet instantiated, we need to wait otherwise the
+     * VirtualFlow will not shift the cells properly.
+     *
+     * @param value
+     */
+    public void setHbarValue(double value) {
+        setHbarValue(value, 0);
+    }
+
+    public void setHbarValue(double value, int count) {
+        if (count > 5) {
+            return;
+        }
+        final int newCount = count + 1;
+        if (flow.getScene() == null) {
+            Platform.runLater(() -> {
+                setHbarValue(value, newCount);
+            });
+            return;
+        }
+        getHBar().setValue(value);
+    }
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/GridVirtualFlow.java b/src/impl/org/controlsfx/spreadsheet/GridVirtualFlow.java
new file mode 100644
index 0000000000000000000000000000000000000000..ea549458ebb9a29a4b6541cddd93fd474cef13fe
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/GridVirtualFlow.java
@@ -0,0 +1,426 @@
+/**
+ * Copyright (c) 2013, 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import com.sun.javafx.scene.control.skin.VirtualFlow;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import javafx.beans.Observable;
+import javafx.beans.binding.When;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ObservableList;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.control.IndexedCell;
+import javafx.scene.control.ScrollBar;
+import javafx.scene.control.TableRow;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.Region;
+import javafx.scene.shape.Rectangle;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+public final class GridVirtualFlow<T extends IndexedCell<?>> extends VirtualFlow<T> {
+    
+    /**
+     * With that comparator we can lay out our rows in the reverse order. That
+     * is to say from the bottom to the very top. In that manner we are sure
+     * that our spanning cells will COVER the cell below so we don't have any
+     * problems with missing hovering, the editor jammed etc.
+     * <br/>
+     *
+     * The only problem is for the fixed column but the {@link #getTopRow(int) }
+     * now returns the very first row and allow us to put some privileged
+     * TableCell in it if they feel the need to be on top in term of z-order.
+     *
+     * FIXME The best would be to put a TreeList of something like that in order
+     * not to sort the rows everytime, need investigation..
+     */
+    private static final Comparator<GridRow> ROWCMP = new Comparator<GridRow>() {
+        @Override
+        public int compare(GridRow firstRow, GridRow secondRow) {
+            //o1.getIndex() < o2.getIndex() ? -1 : +1;
+            return secondRow.getIndex() - firstRow.getIndex();
+        }
+    };
+
+    /***************************************************************************
+     * * Private Fields * *
+     **************************************************************************/
+    private SpreadsheetView spreadSheetView;
+    private final GridViewSkin gridViewSkin;
+    /**
+     * Store the fixedRow in order to place them at the top when necessary.
+     * That is to say, when the VirtualFlow has not already placed one.
+     */
+    private final ArrayList<T> myFixedCells = new ArrayList<>();
+    public final List<Node> sheetChildren;
+
+    /***************************************************************************
+     * * Constructor * *
+     **************************************************************************/
+    public GridVirtualFlow(GridViewSkin gridViewSkin) {
+        super();
+        this.gridViewSkin = gridViewSkin;
+        final ChangeListener<Number> listenerY = new ChangeListener<Number>() {
+            @Override
+            public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
+                layoutTotal();
+            }
+        };
+        getVbar().valueProperty().addListener(listenerY);
+        getHbar().valueProperty().addListener(hBarValueChangeListener);
+        widthProperty().addListener(hBarValueChangeListener);
+        
+        sheetChildren = findSheetChildren();
+        
+        //When we click outside of the grid, we want to deselect all cells.
+        addEventHandler(MouseEvent.MOUSE_PRESSED, (MouseEvent event) -> {
+            if (event.getTarget().getClass() == GridRow.class) {
+                spreadSheetView.getSelectionModel().clearSelection();
+            }
+        });
+    }
+
+    /***************************************************************************
+     * * Public Methods * *
+     **************************************************************************/
+    public void init(SpreadsheetView spv) {
+        /**
+         * The idea is to work-around
+         * https://javafx-jira.kenai.com/browse/RT-36396 in order to have the
+         * same behavior between the vertical scrollBar and the horizontal
+         * scrollBar.
+         */
+        getHbar().maxProperty().addListener(new ChangeListener<Number>() {
+
+            @Override
+            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+                //We want to go page by page.
+                getHbar().setBlockIncrement(getWidth());
+                getHbar().setUnitIncrement(newValue.doubleValue()/20);
+            }
+        });
+
+        this.spreadSheetView = spv;
+       
+        //We clip the rectangle selection with a rectangle, inception style.
+        Rectangle rec = new Rectangle();
+        rec.widthProperty().bind(widthProperty().subtract(new When(getVbar().visibleProperty()).then(getVbar().widthProperty()).otherwise(0)));
+        rec.heightProperty().bind(heightProperty().subtract(new When(getHbar().visibleProperty()).then(getHbar().heightProperty()).otherwise(0)));
+        gridViewSkin.rectangleSelection.setClip(rec);
+        
+        getChildren().add(gridViewSkin.rectangleSelection);
+        
+        spv.getFixedRows().addListener((Observable observable) -> {
+            List<T> toRemove = new ArrayList<>();
+            for (T cell : myFixedCells) {
+                if (!spv.getFixedRows().contains(cell.getIndex())) {
+                    cell.setManaged(false);
+                    cell.setVisible(false);
+                    toRemove.add(cell);
+                }
+            }
+            myFixedCells.removeAll(toRemove);
+        });
+    }
+
+    @Override
+    public void show(int index) {
+        super.show(index);
+        layoutTotal();
+        layoutFixedRows();
+    }
+
+    @Override
+    public void scrollTo(int index) {
+        //If we have some fixedRows, we check if the selected row is not below them
+        if (!getCells().isEmpty() && spreadSheetView.getFixedRows().size() > 0) {
+            double offset = gridViewSkin.getFixedRowHeight();
+
+            while (offset >= 0 && index > 0) {
+                index--;
+                offset -= gridViewSkin.getRowHeight(index);
+            }
+        }
+        super.scrollTo(index);
+
+        layoutTotal();
+        layoutFixedRows();
+                }
+
+    @Override
+    public double adjustPixels(final double delta) {
+        final double returnValue = super.adjustPixels(delta);
+
+        layoutTotal();
+        layoutFixedRows();
+
+        return returnValue;
+    }
+    
+    List<T> getFixedCells(){
+        return myFixedCells;
+    }
+    /***************************************************************************
+     * * Protected Methods * *
+     **************************************************************************/
+
+    /**
+     * We need to return here the very top row in term of "z-order". Because we
+     * will add in this row the TableCell that are in fixedColumn and which
+     * needs to be drawn on top of all others.
+     *
+     * @return
+     */
+    GridRow getTopRow() {
+        if (!sheetChildren.isEmpty()) {
+            return (GridRow) sheetChildren.get(sheetChildren.size() - 1);
+        }
+        return null;
+    }
+    
+    @Override
+    protected void layoutChildren() {
+        /**
+         * In fact, we must do a layout even when editing, because if the user
+         * resize the window during edition, if we block layout, the view will
+         * be in a wrong state.
+         */
+        if (spreadSheetView != null
+                /*&& (spreadSheetView.getEditingCell() == null || spreadSheetView
+                        .getEditingCell().getRow() == -1)*/) {
+            sortRows();
+            super.layoutChildren();
+            layoutTotal();
+            layoutFixedRows();
+            
+            /**
+             * Sometimes, the visible amount is not computed when we have few
+             * big rows. If we detect that case, we must compute it manually
+             * otherwise the Vbar is wrongly set.
+             */
+            if (getVbar().getVisibleAmount() == 0.0
+                    && getVbar().isVisible()
+                    && getCells().size() != getCellCount()) {
+                getVbar().setMax(1);
+                getVbar().setVisibleAmount(getCells().size() / (float) getCellCount());
+            }
+        }
+    }
+
+    /**
+     * Layout all the visible rows
+     */
+    protected void layoutTotal() {
+        sortRows();
+        
+        /**
+         * When we layout, we also remove the cell that have been deported into
+         * other rows in order not to have some TableCell hanging out.
+         */
+        for(GridRow row : gridViewSkin.deportedCells.keySet()){
+            for(CellView cell: gridViewSkin.deportedCells.get(row)){
+                row.removeCell(cell);
+            }
+        }
+        gridViewSkin.deportedCells.clear();
+        // When scrolling fast with fixed Rows, cells is empty and not recreated..
+        if (getCells().isEmpty()) {
+            reconfigureCells();
+        }
+        
+        for (GridRow cell : (List<GridRow>)getCells()) {
+            if (cell != null && cell.getIndex() >= 0 && (!gridViewSkin.hBarValue.get(cell.getIndex()) || gridViewSkin.rowToLayout.get(cell.getIndex()))) {
+                cell.requestLayout();
+            }
+        }
+    }
+
+    protected ScrollBar getVerticalBar() {
+        return getVbar();
+    }
+    protected ScrollBar getHorizontalBar() {
+        return getHbar();
+    }
+
+    @Override
+    protected List<T> getCells() {
+        return super.getCells();
+    }
+
+    /***************************************************************************
+     * * Private Methods * *
+     **************************************************************************/
+
+    /**
+     * WARNING : This is bad but no other options right now. This will find the
+     * sheetChildren of the VirtualFlow, aka where the cells are kept and
+     * clipped. See layoutFixedRows() or getTopRow() for use.
+     *
+     * @return
+     */
+    private List<Node> findSheetChildren(){
+        if(!getChildren().isEmpty()){
+            if(getChildren().get(0) instanceof Region){
+                Region region = (Region) getChildren().get(0);
+                if(!region.getChildrenUnmodifiable().isEmpty()){
+                    if(region.getChildrenUnmodifiable().get(0) instanceof Group){
+                        return ((Group)region.getChildrenUnmodifiable().get(0)).getChildren();
+                    }
+                }
+            }
+        }
+        return new ArrayList<>();
+    }
+    
+    /**
+     * Layout the fixed rows to position them correctly
+     */
+    private void layoutFixedRows() {
+
+		//We must have a cell in ViewPort because otherwise
+        //we short-circuit the VirtualFlow.
+        if (spreadSheetView.getFixedRows().size() > 0 && getFirstVisibleCellWithinViewPort() != null) {
+            sortRows();
+            /**
+             * What I do is just going after the VirtualFlow in order to ADD
+             * (not replace like before) new rows at the top.
+             *
+             * If the VirtualFlow has the row, then I will hide mine and let him
+             * handle. But if the row is missing, then I must show mine in order
+             * to have the fixed row.
+             */
+            T row = null;
+            Integer fixedRowIndex;
+            
+            rows:
+            for (int i = spreadSheetView.getFixedRows().size() - 1; i >= 0; i--) {
+                fixedRowIndex = spreadSheetView.getFixedRows().get(i);
+                T lastCell = getLastVisibleCellWithinViewPort();
+                //If the fixed row is out of bounds
+                if (lastCell != null && fixedRowIndex > lastCell.getIndex()) {
+                    if (row != null) {
+                        row.setVisible(false);
+                        row.setManaged(false);
+                        sheetChildren.remove(row);
+                    }
+                    continue;
+                }
+
+                //We see if the row is laid out by the VirtualFlow
+                for (T virtualFlowCells : getCells()) {
+                    if (virtualFlowCells.getIndex() > fixedRowIndex) {
+                        break;
+                    } else if (virtualFlowCells.getIndex() == fixedRowIndex) {
+                        row = containsRows(fixedRowIndex);
+                        if (row != null) {
+                            row.setVisible(false);
+                            row.setManaged(false);
+                            sheetChildren.remove(row);
+                        }
+                        /**
+                         * OLD COMMENT : We must push to Front only if the row
+                         * is at the very top and has a risk to be recovered.
+                         * This is happening only if this row is translated.
+                         *
+                         * NEW COMMENT: I'm not sure about this.. Since the
+                         * fixedColumn are not in the special top row, we don't
+                         * care if the row is pushed to front.. need
+                         * investigation
+                         */
+                        virtualFlowCells.toFront();
+                        continue rows;
+                    }
+                }
+                
+                row = containsRows(fixedRowIndex);
+                if (row == null) {
+                    /**
+                     * getAvailableCell is not added our cell to the ViewPort in some cases.
+                     * So we need to instantiate it ourselves.
+                     */
+                    row = getCreateCell().call(this);
+                    row.getProperties().put("newcell", null); //$NON-NLS-1$
+                	 
+                    setCellIndex(row, fixedRowIndex);
+                    resizeCellSize(row);
+                    myFixedCells.add(row);
+                }
+                
+                /**
+                 * Sometime, when we set a new Grid on a SpreadsheetView without recreating it,
+                 * we can end up with some rows not being added to the ViewPort.
+                 * So we must be sure it's in and add it ourself otherwise.
+                 */
+                if(!sheetChildren.contains(row)){
+                    sheetChildren.add(row);
+                }
+               
+                row.setManaged(true);
+                row.setVisible(true);
+                row.toFront();
+                row.requestLayout();
+            }
+        }
+    }
+
+    /**
+     * Verify if the row has been added to myFixedCell
+     * @param i
+     * @return
+     */
+    private T containsRows(int i){
+    	for(T cell:myFixedCells){
+    		if(cell.getIndex() == i)
+    			return cell;
+    	}
+    	return null;
+    }
+    /**
+     * Sort the rows so that they stay in order for layout
+     */
+    private void sortRows() {
+        final List<GridRow> temp = (List<GridRow>) getCells();
+        final List<GridRow> tset = new ArrayList<>(temp);
+        Collections.sort(tset, ROWCMP);
+        for (final TableRow<ObservableList<SpreadsheetCell>> r : tset) {
+            r.toFront();
+        }
+    }
+    
+    private final ChangeListener<Number> hBarValueChangeListener = new ChangeListener<Number>() {
+        @Override
+        public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
+            gridViewSkin.hBarValue.clear();
+        }
+    };
+}
+
diff --git a/src/impl/org/controlsfx/spreadsheet/HorizontalHeader.java b/src/impl/org/controlsfx/spreadsheet/HorizontalHeader.java
new file mode 100644
index 0000000000000000000000000000000000000000..6540da870224f6196cbb20f6c63401d5e047cc66
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/HorizontalHeader.java
@@ -0,0 +1,349 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import com.sun.javafx.scene.control.skin.NestedTableColumnHeader;
+import com.sun.javafx.scene.control.skin.TableColumnHeader;
+import com.sun.javafx.scene.control.skin.TableHeaderRow;
+import java.util.BitSet;
+import java.util.List;
+import javafx.application.Platform;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableView.TableViewSelectionModel;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.shape.Rectangle;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetColumn;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+/**
+ * The set of horizontal (column) headers.
+ */
+public class HorizontalHeader extends TableHeaderRow {
+
+    final GridViewSkin gridViewSkin;
+
+    // Indicate whether the this HorizontalHeader is activated or not
+    private boolean working = true;
+    /**
+     * When the columns header are clicked, we consider the column as selected.
+     * This BitSet is reset when a modification on cells is done.
+     */
+    protected BitSet selectedColumns = new BitSet();
+
+    /***************************************************************************
+     * 
+     * Constructor
+     * 
+     **************************************************************************/
+    public HorizontalHeader(final GridViewSkin skin) {
+        super(skin);
+        gridViewSkin = skin;
+    }
+
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    public void init() {
+        SpreadsheetView spv = gridViewSkin.handle.getView();
+        updateHorizontalHeaderVisibility(spv.isShowColumnHeader());
+
+        //Visibility of vertical Header listener
+        spv.showRowHeaderProperty().addListener(verticalHeaderListener);
+        gridViewSkin.verticalHeader.verticalHeaderWidthProperty().addListener(verticalHeaderListener);
+
+        //Visibility of horizontal Header listener
+        spv.showColumnHeaderProperty().addListener(horizontalHeaderVisibilityListener);
+
+        //Selection listener to highlight header
+        gridViewSkin.getSelectedColumns().addListener(selectionListener);
+
+        //Fixed Column listener to change style of header
+        spv.getFixedColumns().addListener(fixedColumnsListener);
+
+        Platform.runLater(() -> {
+            //We are doing that because some columns may be already fixed.
+            for (SpreadsheetColumn column : spv.getFixedColumns()) {
+                fixColumn(column);
+            }
+            requestLayout();
+            /**
+             * Clicking on header select the whole column.
+             */
+            installHeaderMouseEvent();
+        });
+
+        /**
+         * When we are setting a new Grid (model) on the SpreadsheetView, it
+         * appears that the headers are re-created. So we need to listen to
+         * those changes in order to re-apply our css style class. Otherwise
+         * we'll end up with fixedColumns but no graphic confirmation.
+         */
+        getRootHeader().getColumnHeaders().addListener((Observable o) -> {
+            for (SpreadsheetColumn fixItem : spv.getFixedColumns()) {
+                fixColumn(fixItem);
+            }
+            updateHighlightSelection();
+            installHeaderMouseEvent();
+        });
+    }
+
+    @Override
+    public HorizontalHeaderColumn getRootHeader() {
+        return (HorizontalHeaderColumn) super.getRootHeader();
+    }
+
+    void clearSelectedColumns(){
+        selectedColumns.clear();
+    }
+    /**************************************************************************
+     * 
+     * Protected methods
+     * 
+     **************************************************************************/
+    @Override
+    protected void updateTableWidth() {
+        super.updateTableWidth();
+        // snapping added for RT-19428
+        double padding = 0;
+
+        if (working && gridViewSkin != null
+                && gridViewSkin.spreadsheetView != null
+                && gridViewSkin.spreadsheetView.showRowHeaderProperty().get()
+                && gridViewSkin.verticalHeader != null) {
+            padding += gridViewSkin.verticalHeader.getVerticalHeaderWidth();
+        }
+
+        Rectangle clip = ((Rectangle) getClip());
+        
+        clip.setWidth(clip.getWidth() == 0 ? 0 : clip.getWidth() - padding);
+    }
+
+    @Override
+    protected void updateScrollX() {
+        super.updateScrollX();
+        gridViewSkin.horizontalPickers.updateScrollX();
+        
+        if (working) {
+            requestLayout();
+            getRootHeader().layoutFixedColumns();
+        }
+    }
+
+    @Override
+    protected NestedTableColumnHeader createRootHeader() {
+        return new HorizontalHeaderColumn(getTableSkin(), null);
+    }
+
+    /**************************************************************************
+     * 
+     * Private methods.
+     * 
+     **************************************************************************/
+    
+    /**
+     * When we click on header, we want to select the whole column.
+     */
+    private void installHeaderMouseEvent() {
+        for (final TableColumnHeader columnHeader : getRootHeader().getColumnHeaders()) {
+            EventHandler<MouseEvent> mouseEventHandler = (MouseEvent mouseEvent) -> {
+                if (mouseEvent.isPrimaryButtonDown()) {
+                    headerClicked((TableColumn) columnHeader.getTableColumn(), mouseEvent);
+                }
+            };
+            columnHeader.getChildrenUnmodifiable().get(0).setOnMousePressed(mouseEventHandler);
+        }
+    }
+    /**
+     * If a header is clicked, we must select the whole column. If Control key of
+     * Shift key is pressed, we must not deselect the previous selection but
+     * just act like the {@link GridViewBehavior} would.
+     *
+     * @param column
+     * @param event
+     */
+    private void headerClicked(TableColumn column, MouseEvent event) {
+        TableViewSelectionModel<ObservableList<SpreadsheetCell>> sm = gridViewSkin.handle.getGridView().getSelectionModel();
+        int lastRow = gridViewSkin.spreadsheetView.getGrid().getRowCount() - 1;
+        int indexColumn = column.getTableView().getColumns().indexOf(column);
+        TablePosition focusedPosition = sm.getTableView().getFocusModel().getFocusedCell();
+        if (event.isShortcutDown()) {
+            BitSet tempSet = (BitSet) selectedColumns.clone();
+            sm.selectRange(0, column, lastRow, column);
+            selectedColumns.or(tempSet);
+            selectedColumns.set(indexColumn);
+        } else if (event.isShiftDown() && focusedPosition != null && focusedPosition.getTableColumn() != null) {
+            sm.clearSelection();
+            sm.selectRange(0, column, lastRow, focusedPosition.getTableColumn());
+            sm.getTableView().getFocusModel().focus(0, focusedPosition.getTableColumn());
+            int min = Math.min(indexColumn, focusedPosition.getColumn());
+            int max = Math.max(indexColumn, focusedPosition.getColumn());
+            selectedColumns.set(min, max + 1);
+        } else {
+            sm.clearSelection();
+            sm.selectRange(0, column, lastRow, column);
+            //And we want to have the focus on the first cell in order to be able to copy/paste between columns.
+            sm.getTableView().getFocusModel().focus(0, column);
+            selectedColumns.set(indexColumn);
+        }
+    }
+    /**
+     * Whether the Vertical Header is showing, we need to update the width
+     * because some space on the left will be available/used.
+     */
+    private final InvalidationListener verticalHeaderListener = new InvalidationListener() {
+
+        @Override
+        public void invalidated(Observable observable) {
+            updateTableWidth();
+        }
+    };
+
+    /**
+     * Whether the Horizontal Header is showing, we need to toggle its
+     * visibility.
+     */
+    private final ChangeListener<Boolean> horizontalHeaderVisibilityListener = new ChangeListener<Boolean>() {
+        @Override
+        public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
+            updateHorizontalHeaderVisibility(arg2);
+        }
+    };
+
+    /**
+     * When we fix/unfix some columns, we change the style of the Label header
+     * text
+     */
+    private final ListChangeListener<SpreadsheetColumn> fixedColumnsListener = new ListChangeListener<SpreadsheetColumn>() {
+
+        @Override
+        public void onChanged(javafx.collections.ListChangeListener.Change<? extends SpreadsheetColumn> change) {
+            while (change.next()) {
+               //If we unfix a column
+               for (SpreadsheetColumn remitem : change.getRemoved()) {
+                   unfixColumn(remitem);
+               }
+               //If we fix one
+               for (SpreadsheetColumn additem : change.getAddedSubList()) {
+                   fixColumn(additem);
+               }
+            }
+            updateHighlightSelection();
+        }
+    };
+
+    /**
+     * Fix this column regarding the style
+     *
+     * @param column
+     */
+    private void fixColumn(SpreadsheetColumn column) {
+        addStyleHeader(gridViewSkin.spreadsheetView.getColumns().indexOf(column));
+    }
+
+    /**
+     * Unfix this column regarding the style
+     *
+     * @param column
+     */
+    private void unfixColumn(SpreadsheetColumn column) {
+        removeStyleHeader(gridViewSkin.spreadsheetView.getColumns().indexOf(column));
+    }
+
+    /**
+     * Add the fix style of the header Label of the specified column
+     *
+     * @param i
+     */
+    private void removeStyleHeader(Integer i) {
+        if (getRootHeader().getColumnHeaders().size() > i) {
+            getRootHeader().getColumnHeaders().get(i).getStyleClass().removeAll("fixed"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Remove the fix style of the header Label of the specified column
+     *
+     * @param i
+     */
+    private void addStyleHeader(Integer i) {
+        if (getRootHeader().getColumnHeaders().size() > i) {
+            getRootHeader().getColumnHeaders().get(i).getStyleClass().addAll("fixed"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * When we select some cells, we want the header to be highlighted
+     */
+    private final InvalidationListener selectionListener = new InvalidationListener() {
+        @Override
+        public void invalidated(Observable valueModel) {
+            updateHighlightSelection();
+        }
+    };
+
+    /**
+     * Highlight the header Label when selection change.
+     */
+    private void updateHighlightSelection() {
+        for (final TableColumnHeader i : getRootHeader().getColumnHeaders()) {
+            i.getStyleClass().removeAll("selected"); //$NON-NLS-1$
+
+        }
+        final List<Integer> selectedColumns = gridViewSkin.getSelectedColumns();
+        for (final Integer i : selectedColumns) {
+            if (getRootHeader().getColumnHeaders().size() > i) {
+                getRootHeader().getColumnHeaders().get(i).getStyleClass()
+                        .addAll("selected"); //$NON-NLS-1$
+            }
+        }
+
+    }
+
+    private void updateHorizontalHeaderVisibility(boolean visible) {
+        working = visible;
+        setManaged(working);
+        if (!visible) {
+            getStyleClass().add("invisible"); //$NON-NLS-1$
+        } else {
+            getStyleClass().remove("invisible"); //$NON-NLS-1$
+            requestLayout();
+            getRootHeader().layoutFixedColumns();
+            updateHighlightSelection();
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/HorizontalHeaderColumn.java b/src/impl/org/controlsfx/spreadsheet/HorizontalHeaderColumn.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8d7726980becdd302d6950f70f2a8d02a638709
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/HorizontalHeaderColumn.java
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+import javafx.event.EventHandler;
+import javafx.scene.control.TableColumnBase;
+import javafx.scene.input.MouseEvent;
+
+import com.sun.javafx.scene.control.skin.NestedTableColumnHeader;
+import com.sun.javafx.scene.control.skin.TableColumnHeader;
+import com.sun.javafx.scene.control.skin.TableViewSkinBase;
+import javafx.beans.Observable;
+import javafx.beans.value.ObservableValue;
+
+/**
+ * A cell column header.
+ */
+public class HorizontalHeaderColumn extends NestedTableColumnHeader {
+
+    int lastColumnResized = -1;
+    
+    public HorizontalHeaderColumn(
+            TableViewSkinBase<?, ?, ?, ?, ?, ?> skin, TableColumnBase<?, ?> tc) {
+        super(skin, tc);
+        /**
+         * Resolve https://bitbucket.org/controlsfx/controlsfx/issue/395
+         * and https://bitbucket.org/controlsfx/controlsfx/issue/434
+         */
+        widthProperty().addListener((Observable observable) -> {
+            ((GridViewSkin)skin).hBarValue.clear();
+            ((GridViewSkin)skin).rectangleSelection.updateRectangle();
+        });
+        
+        /**
+         * We want to resize all other selected columns when we resize one.
+         *
+         * I cannot really determine when a resize is finished. Apparently, when
+         * this variable Layout is set to 0, it means the drag is done, so until
+         * a beter solution is shown, it will do the trick.
+         */
+        columnReorderLine.layoutXProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
+            HorizontalHeader headerRow = (HorizontalHeader) ((GridViewSkin) skin).getTableHeaderRow();
+            GridViewSkin mySkin = ((GridViewSkin) skin);
+            if (newValue.intValue() == 0 && lastColumnResized >= 0) {
+                if (headerRow.selectedColumns.get(lastColumnResized)) {
+                    double width1 = mySkin.getColumns().get(lastColumnResized).getWidth();
+                    for (int i = headerRow.selectedColumns.nextSetBit(0); i >= 0; i = headerRow.selectedColumns.nextSetBit(i + 1)) {
+                        mySkin.getColumns().get(i).setPrefWidth(width1);
+                    }
+                }
+            }
+        });
+    }
+
+    @Override
+    protected TableColumnHeader createTableColumnHeader(final TableColumnBase col) {
+        TableViewSkinBase<?,?,?,?,?,TableColumnBase<?,?>> tableViewSkin = getTableViewSkin();
+        if (col.getColumns().isEmpty()) {
+            final TableColumnHeader columnHeader = new TableColumnHeader(tableViewSkin, col);
+            /**
+             * When the user double click on a header, we want to resize the
+             * column to fit the content.
+             */
+            columnHeader.setOnMousePressed(new EventHandler<MouseEvent>() {
+                @Override
+                public void handle(MouseEvent mouseEvent) {
+                    if (mouseEvent.getClickCount() == 2 && mouseEvent.isPrimaryButtonDown()) {
+                        ((GridViewSkin) (Object) tableViewSkin).resize(col, -1);
+                    }
+                }
+            });
+            return columnHeader;
+        } else {
+            return new HorizontalHeaderColumn(getTableViewSkin(), col);
+        }
+    }
+
+    @Override
+    protected void layoutChildren() {
+        super.layoutChildren();
+        layoutFixedColumns();
+    }
+
+    /**
+     * We want ColumnHeader to be fixed when we freeze some columns
+     *
+     */
+    public void layoutFixedColumns() {
+        SpreadsheetHandle handle = ((GridViewSkin) (Object) getTableViewSkin()).handle;
+        final SpreadsheetView spreadsheetView = handle.getView();
+        if (handle.getCellsViewSkin() == null || getChildren().isEmpty()) {
+            return;
+        }
+        double hbarValue = handle.getCellsViewSkin().getHBar().getValue();
+
+        final int labelHeight = (int) getChildren().get(0).prefHeight(-1);
+        double fixedColumnWidth = 0;
+        double x = snappedLeftInset();
+        int max = getColumnHeaders().size();
+        max = max > spreadsheetView.getColumns().size() ? spreadsheetView.getColumns().size() : max;
+        for (int j = 0 ; j < max; j++) {
+            final TableColumnHeader n = getColumnHeaders().get(j);
+            final double prefWidth = snapSize(n.prefWidth(-1));
+            n.setPrefHeight(24.0);
+            //If the column is fixed
+            if (spreadsheetView.getFixedColumns().indexOf(spreadsheetView.getColumns().get(j)) != -1) {
+                double tableCellX = 0;
+                //If the column is hidden we have to translate it
+                if (hbarValue + fixedColumnWidth > x) {
+
+                    tableCellX = Math.abs(hbarValue - x + fixedColumnWidth);
+
+                    n.toFront();
+                    fixedColumnWidth += prefWidth;
+                }
+                n.relocate(x + tableCellX, labelHeight + snappedTopInset());
+            }
+
+            x += prefWidth;
+        }
+
+    }
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/HorizontalPicker.java b/src/impl/org/controlsfx/spreadsheet/HorizontalPicker.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ef50ab7ab6a1a9a38a36e1d83b20e41616a318a
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/HorizontalPicker.java
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2014 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import com.sun.javafx.scene.control.skin.TableColumnHeader;
+import java.util.Stack;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.event.EventHandler;
+import javafx.scene.control.Label;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.StackPane;
+import javafx.scene.shape.Rectangle;
+import org.controlsfx.control.spreadsheet.Picker;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+/**
+ *
+ * This class will display all the available pickers. It is a StackPane clipped
+ * which contain a inner Region that display the picker. In that way, we don't
+ * need to re-layout every time but just "slide" the inner Region inside this
+ * class so that the pickers are sliding along with the TableColumnHeaders.
+ */
+public class HorizontalPicker extends StackPane {
+
+    private static final String PICKER_INDEX = "PickerIndex"; //$NON-NLS-1$
+
+    private final HorizontalHeader horizontalHeader;
+
+    private final SpreadsheetView spv;
+    private final Stack<Label> pickerPile;
+    private final Stack<Label> pickerUsed;
+
+    private final InnerHorizontalPicker innerPicker = new InnerHorizontalPicker();
+
+    public HorizontalPicker(HorizontalHeader horizontalHeader, SpreadsheetView spv) {
+        this.horizontalHeader = horizontalHeader;
+        this.spv = spv;
+
+        pickerPile = new Stack<>();
+        pickerUsed = new Stack<>();
+
+        //Clip this StackPane just like the TableHeaderRow.
+        Rectangle clip = new Rectangle();
+        clip.setSmooth(true);
+        clip.setHeight(VerticalHeader.PICKER_SIZE);
+        clip.widthProperty().bind(horizontalHeader.widthProperty());
+        setClip(clip);
+
+        getChildren().add(innerPicker);
+
+        horizontalHeader.getRootHeader().getColumnHeaders().addListener(layoutListener);
+        spv.getColumnPickers().addListener(layoutListener);
+    }
+
+    @Override
+    protected void layoutChildren() {
+        //Just relocate the inner for sliding.
+        innerPicker.relocate(horizontalHeader.getRootHeader().getLayoutX(), snappedTopInset());
+        //We must turn off pickers that are behind fixed columns
+        for (Label label : pickerUsed) {
+            label.setVisible(label.getLayoutX() + innerPicker.getLayoutX() + label.getWidth() > horizontalHeader.gridViewSkin.fixedColumnWidth);
+        }
+    }
+
+    /**
+     * Method called by the HorizontalHeader in order to slide the pickers.
+     */
+    public void updateScrollX() {
+        requestLayout();
+    }
+
+    private Label getPicker(Picker picker) {
+        Label pickerLabel;
+        if (pickerPile.isEmpty()) {
+            pickerLabel = new Label();
+            pickerLabel.getStyleClass().addListener(layoutListener);
+            pickerLabel.setOnMouseClicked(pickerMouseEvent);
+        } else {
+            pickerLabel = pickerPile.pop();
+        }
+        pickerUsed.push(pickerLabel);
+        pickerLabel.getStyleClass().setAll(picker.getStyleClass());
+        pickerLabel.getProperties().put(PICKER_INDEX, picker);
+        return pickerLabel;
+    }
+
+    private final EventHandler<MouseEvent> pickerMouseEvent = (MouseEvent mouseEvent) -> {
+        Label picker = (Label) mouseEvent.getSource();
+
+        ((Picker) picker.getProperties().get(PICKER_INDEX)).onClick();
+    };
+
+    /**
+     * Inner class that will lay out all the pickers.
+     */
+    private class InnerHorizontalPicker extends Region {
+
+        @Override
+        protected void layoutChildren() {
+            pickerPile.addAll(pickerUsed.subList(0, pickerUsed.size()));
+            //Unbind every picker used before setting new ones.
+            for (Label label : pickerUsed) {
+                label.layoutXProperty().unbind();
+                label.setVisible(true);
+            }
+            pickerUsed.clear();
+
+            getChildren().clear();
+            int index = 0;
+            for (TableColumnHeader column : horizontalHeader.getRootHeader().getColumnHeaders()) {
+                if (spv.getColumnPickers().containsKey(index)) {
+                    Label label = getPicker(spv.getColumnPickers().get(index));
+                    label.resize(column.getWidth(), VerticalHeader.PICKER_SIZE);
+                    label.layoutXProperty().bind(column.layoutXProperty());
+
+                    getChildren().add(0, label);
+                }
+                index++;
+            }
+        }
+    }
+
+    private final InvalidationListener layoutListener = (Observable arg0) -> {
+        innerPicker.requestLayout();
+    };
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/RectangleSelection.java b/src/impl/org/controlsfx/spreadsheet/RectangleSelection.java
new file mode 100644
index 0000000000000000000000000000000000000000..7496914504cd850a0055a6b1ac537149faca7254
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/RectangleSelection.java
@@ -0,0 +1,436 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import java.util.List;
+import java.util.TreeSet;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.event.EventHandler;
+import javafx.scene.control.IndexedCell;
+import javafx.scene.control.TablePosition;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.shape.Rectangle;
+import org.controlsfx.control.spreadsheet.Grid;
+import org.controlsfx.control.spreadsheet.GridChange;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetColumn;
+
+/**
+ *
+ * This class extends Rectangle and will draw a rectangle with a border to the
+ * selection.
+ */
+public class RectangleSelection extends Rectangle {
+
+    private final GridViewSkin skin;
+    private final TableViewSpanSelectionModel sm;
+    private final SelectionRange selectionRange;
+
+    public RectangleSelection(GridViewSkin skin, TableViewSpanSelectionModel sm) {
+        this.skin = skin;
+        this.sm = sm;
+        getStyleClass().add("selection-rectangle"); //$NON-NLS-1$
+        setMouseTransparent(true);
+
+        selectionRange = new SelectionRange();
+        skin.getVBar().valueProperty().addListener(layoutListener);
+
+        //When draging, it's not working properly so we remove the rectangle.
+        skin.getVBar().addEventFilter(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() {
+
+            @Override
+            public void handle(MouseEvent event) {
+                skin.getVBar().valueProperty().removeListener(layoutListener);
+                setVisible(false);
+                skin.getVBar().addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() {
+
+                    @Override
+                    public void handle(MouseEvent event) {
+                        skin.getVBar().removeEventFilter(MouseEvent.MOUSE_RELEASED, this);
+                        skin.getVBar().valueProperty().addListener(layoutListener);
+                        updateRectangle();
+                    }
+                });
+            }
+        });
+
+        skin.getHBar().valueProperty().addListener(layoutListener);
+        sm.getSelectedCells().addListener((Observable observable) -> {
+            skin.getHorizontalHeader().clearSelectedColumns();
+            skin.verticalHeader.clearSelectedRows();
+            selectionRange.fill(sm.getSelectedCells());
+            updateRectangle();
+        });
+    }
+
+    private final InvalidationListener layoutListener = (Observable observable) -> {
+        updateRectangle();
+    };
+
+    public final void updateRectangle() {
+        if (sm.getSelectedCells().isEmpty()
+                || skin.getSelectedRows().isEmpty()
+                || skin.getSelectedColumns().isEmpty()
+                || selectionRange.range == null) {
+            setVisible(false);
+            return;
+        }
+
+        IndexedCell topRowCell = skin.getFlow().getTopRow();
+        if(topRowCell == null){
+            return;
+        }
+        //We fetch the first and last row currently displayed
+        int topRow = topRowCell.getIndex();
+        IndexedCell bottomRowCell = skin.getFlow().getCells().get(skin.getFlow().getCells().size() - 1);
+        if(bottomRowCell == null){
+            return;
+        }
+        int bottomRow = bottomRowCell.getIndex();
+
+        int minRow = selectionRange.range.getTop();
+        if (minRow > bottomRow) {
+            setVisible(false);
+            return;
+        }
+        minRow = Math.max(minRow, topRow);
+
+        int maxRow = selectionRange.range.getBottom();
+        if (maxRow < topRow) {
+            setVisible(false);
+            return;
+        }
+
+        maxRow = Math.min(maxRow, bottomRow);
+        int minColumn = selectionRange.range.getLeft();
+        int maxColumn = selectionRange.range.getRight();
+
+        GridRow gridMinRow = skin.getRowIndexed(minRow);
+        if (gridMinRow == null) {
+            setVisible(false);
+            return;
+        }
+
+        Grid grid = skin.spreadsheetView.getGrid();
+        if (maxRow >= grid.getRowCount() || maxColumn >= grid.getColumnCount()) {
+            setVisible(false);
+            return;
+        }
+        SpreadsheetCell cell = grid.getRows().get(maxRow).get(maxColumn);
+        handleHorizontalPositioning(minColumn, maxColumn, cell.getColumnSpan());
+
+        //If we are out of sight
+        if (getX() + getWidth() < 0) {
+            setVisible(false);
+            return;
+        }
+
+        GridRow gridMaxRow = skin.getRowIndexed(maxRow);
+        if (gridMaxRow == null) {
+            setVisible(false);
+            return;
+        }
+        setVisible(true);
+
+        handleVerticalPositioning(minRow, maxRow, gridMinRow, gridMaxRow, cell.getRowSpan());
+    }
+
+    /**
+     * This will compute and assign the y and height properties of the
+     * rectangle.
+     *
+     * @param minRow
+     * @param maxRow
+     * @param gridMinRow
+     */
+    private void handleVerticalPositioning(int minRow, int maxRow, GridRow gridMinRow, GridRow gridMaxRow, int rowSpan) {
+        double height = 0;
+        for (int i = maxRow; i <= maxRow /*+ (rowSpan - 1)*/; ++i) {
+            height += skin.getRowHeight(i);
+        }
+
+        /**
+         * If we are not in fixed row, we will just take the layout Y, and if
+         * it's below some of our fixed rows, we will take the fixedRowheight as
+         * value.
+         */
+        if (!skin.getCurrentlyFixedRow().contains(minRow)) {
+            yProperty().unbind();
+            //If we have fixedRows, we do not want to overlap them with the rectangle.
+            if (gridMinRow.getLayoutY() < skin.getFixedRowHeight()) {
+                setY(skin.getFixedRowHeight());
+            } else {
+                yProperty().bind(gridMinRow.layoutYProperty());
+            }
+            /**
+             * If we are in fixedRow, we cannot trust the layoutY alone. We also
+             * need to rely on the verticalShift for shifting the rectangle to
+             * the right starting position.\n
+             *
+             */
+        } else {
+            yProperty().bind(gridMinRow.layoutYProperty().add(gridMinRow.verticalShift));
+        }
+
+        /**
+         * Finally we compute the height by subtracting our starting point to
+         * the ending point.
+         */
+        heightProperty().bind(gridMaxRow.layoutYProperty().add(gridMaxRow.verticalShift).subtract(yProperty()).add(height));
+    }
+
+    /**
+     * This will compute and assign the x and width propertis of the Rectangle.
+     *
+     * @param minColumn
+     * @param maxColumn
+     */
+    private void handleHorizontalPositioning(int minColumn, int maxColumn, int columnSpan) {
+        double x = 0;
+
+        final List<SpreadsheetColumn> columns = skin.spreadsheetView.getColumns();
+        if(columns.size() <= minColumn || columns.size() <= maxColumn){
+            return;
+        }
+        //We first compute the total space between the left edge and our first column
+        for (int i = 0; i < minColumn; ++i) {
+            //Here we use Ceil because we want to "snapSize" otherwise we may end up with a weird shift.
+            x += snapSize(columns.get(i).getWidth());
+        }
+        
+
+        /**
+         * We then substract the value of the Hbar in order to place it properly
+         * because 0 means the left edge or the SpreadsheetView and we want to
+         * consider the left edge of the viewport of the virtualFlow.
+         */
+        x -= skin.getHBar().getValue();
+
+        //Then we compute the width by adding the space between the min and max column
+        double width = 0;
+        for (int i = minColumn; i <= maxColumn /*+ (columnSpan - 1)*/; ++i) {
+            width += snapSize(columns.get(i).getWidth());
+        }
+
+        //FIXED COLUMNS
+        /**
+         * If the selection is not on a fixed column, we may have the case where
+         * the first selected cell will be hid by a fixed column. If so, we must
+         * translate the starting point in because the rectangle must also be
+         * hidden by the fixed column.
+         */
+        if (!skin.spreadsheetView.getFixedColumns().contains(columns.get(minColumn))) {
+            if (x < skin.fixedColumnWidth) {
+                //Since I translate the starting point, I must reduce the width by the value I'm translating.
+                width -= skin.fixedColumnWidth - x;
+                x = skin.fixedColumnWidth;
+            }
+            /**
+             * If the maxColumn is contained within the fixed column, we may
+             * look at the starting point and the ending point. Because prior
+             * computation are wrong since our columns are fixed on the left. So
+             * there initial position are worthless and we must consider their
+             * current position compared to each other.
+             *
+             */
+        } else {
+            /**
+             * If x + width is inferior, we can re-compute the width by checking
+             * our fixed columns interval
+             */
+            if (x + width < skin.fixedColumnWidth) {
+                x = 0;
+                width = 0;
+                for (SpreadsheetColumn column : skin.spreadsheetView.getFixedColumns()) {
+                    int indexColumn = columns.indexOf(column);
+                    if (indexColumn < minColumn && indexColumn != minColumn) {
+                        x += snapSize(column.getWidth());
+                    }
+                    if (indexColumn >= minColumn && indexColumn <= maxColumn) {
+                        width += snapSize(column.getWidth());
+                    }
+                }
+                /**
+                 * If just x is inferior to fixedColumnWidth, we just adjust the
+                 * width by substracting the gap between the original x and the
+                 * new x.
+                 */
+            } else if (x < skin.fixedColumnWidth) {
+                double tempX = 0;
+                for (SpreadsheetColumn column : skin.spreadsheetView.getFixedColumns()) {
+                    int indexColumn = columns.indexOf(column);
+                    if (indexColumn < minColumn && indexColumn != minColumn) {
+                        tempX += snapSize(column.getWidth());
+                    }
+                }
+                width -= tempX - x;
+                x = tempX;
+            }
+        }
+        setX(x);
+        setWidth(width);
+    }
+
+    /**
+     * Returns a value ceiled to the nearest pixel.
+     *
+     * @param value the size value to be snapped
+     * @return value ceiled to nearest pixel
+     */
+    private double snapSize(double value) {
+        return Math.ceil(value);
+    }
+    
+    /**
+     * Utility class to transform a list of selected cells into a union of
+     * ranges.
+     */
+    public static class SelectionRange {
+
+        private final TreeSet<Long> set = new TreeSet<>();
+        private GridRange range;
+
+        public SelectionRange() {
+        }
+
+        /**
+         * Construct a SelectionRange with a List of Pair where the value is the
+         * row (of the WsGrid) and the value is column(of the WsGrid).
+         *
+         * @param list
+         */
+        public void fill(List<TablePosition> list) {
+            set.clear();
+            for (TablePosition pos : list) {
+                set.add(key(pos.getRow(), pos.getColumn()));
+            }
+            computeRange();
+        }
+        
+        public void fillGridRange(List<GridChange> list) {
+            set.clear();
+            for (GridChange pos : list) {
+                set.add(key(pos.getRow(), pos.getColumn()));
+            }
+            computeRange();
+        }
+
+        public GridRange getRange(){
+            return range;
+        }
+        private Long key(int row, int column) {
+            return (((long) row) << 32) | column;
+        }
+
+        private int getRow(Long l) {
+            return (int) (l >> 32);
+        }
+
+        private int getColumn(Long l) {
+            return (int) (l & 0xffFFffFF);
+        }
+
+        /**
+         * return a list of WsGridRange
+         *
+         * @return
+         */
+        private void computeRange() {
+            range = null;
+            while (!set.isEmpty()) {
+                if (range != null) {
+                    range = null;
+                    return;
+                }
+
+                long first = set.first();
+                set.remove(first);
+
+                int row = getRow(first);
+                int column = getColumn(first);
+
+                //Go in row
+                while (set.contains(key(row, column + 1))) {
+                    ++column;
+                    set.remove(key(row, column));
+                }
+
+                //Go in column
+                boolean flag = true;
+                while (flag) {
+                    ++row;
+                    for (int col = getColumn(first); col <= column; ++col) {
+                        if (!set.contains(key(row, col))) {
+                            flag = false;
+                            break;
+                        }
+                    }
+                    if (flag) {
+                        for (int col = getColumn(first); col <= column; ++col) {
+                            set.remove(key(row, col));
+                        }
+                    } else {
+                        --row;
+                    }
+                }
+                range = new GridRange(getRow(first), row, getColumn(first), column);
+            }
+        }
+    }
+
+    public static class GridRange {
+
+        private final int top;
+        private final int bottom;
+        private final int left;
+        private final int right;
+
+        public GridRange(int top, int bottom, int left, int right) {
+            this.top = top;
+            this.bottom = bottom;
+            this.left = left;
+            this.right = right;
+        }
+
+        public int getTop() {
+            return top;
+        }
+
+        public int getBottom() {
+            return bottom;
+        }
+
+        public int getLeft() {
+            return left;
+        }
+
+        public int getRight() {
+            return right;
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/SelectedCellsMapTemp.java b/src/impl/org/controlsfx/spreadsheet/SelectedCellsMapTemp.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d37392fdabe5499aa707e8ec12093639f5a9268
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/SelectedCellsMapTemp.java
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2014 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeMap;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.collections.transformation.SortedList;
+import javafx.scene.control.TablePositionBase;
+
+/**
+ * This class is copied from com.sun.javafx.scene.control.SelectedCellsMap
+ * temporary in 8u20 to resolve https://javafx-jira.kenai.com/browse/RT-38306
+ * 
+ * Will be removed in 8u40
+ *
+ * @param <T>
+ */
+public class SelectedCellsMapTemp<T extends TablePositionBase> {
+    private final ObservableList<T> selectedCells;
+    private final ObservableList<T> sortedSelectedCells;
+
+    private final Map<Integer, BitSet> selectedCellBitSetMap;
+
+    public SelectedCellsMapTemp(final ListChangeListener<T> listener) {
+        selectedCells = FXCollections.<T>observableArrayList();
+        sortedSelectedCells = new SortedList<>(selectedCells, (T o1, T o2) -> {
+            int result =  o1.getRow() - o2.getRow();
+           return result == 0 ? (o1.getColumn() - o2.getColumn())  : result;
+        });
+        sortedSelectedCells.addListener(listener);
+
+        selectedCellBitSetMap = new TreeMap<>((o1, o2) -> o1.compareTo(o2));
+    }
+
+    public int size() {
+        return selectedCells.size();
+    }
+
+    public T get(int i) {
+        if (i < 0) {
+            return null;
+        }
+        return sortedSelectedCells.get(i);
+    }
+
+    public void add(T tp) {
+        final int row = tp.getRow();
+        final int columnIndex = tp.getColumn();
+
+        // update the bitset map
+        BitSet bitset;
+        if (! selectedCellBitSetMap.containsKey(row)) {
+            bitset = new BitSet();
+            selectedCellBitSetMap.put(row, bitset);
+        } else {
+            bitset = selectedCellBitSetMap.get(row);
+        }
+
+        if (columnIndex >= 0) {
+            boolean isAlreadySet = bitset.get(columnIndex);
+            bitset.set(columnIndex);
+
+            if (! isAlreadySet) {
+                // add into the list
+                selectedCells.add(tp);
+            }
+        } else {
+            // FIXME slow path (for now)
+            if (! selectedCells.contains(tp)) {
+                selectedCells.add(tp);
+            }
+        }
+    }
+
+    public void addAll(Collection<T> cells) {
+        // update bitset
+        for (T tp : cells) {
+            final int row = tp.getRow();
+            final int columnIndex = tp.getColumn();
+
+            // update the bitset map
+            BitSet bitset;
+            if (! selectedCellBitSetMap.containsKey(row)) {
+                bitset = new BitSet();
+                selectedCellBitSetMap.put(row, bitset);
+            } else {
+                bitset = selectedCellBitSetMap.get(row);
+            }
+
+            if (columnIndex < 0) {
+                continue;
+            }
+
+            bitset.set(columnIndex);
+        }
+
+        // add into the list
+        selectedCells.addAll(cells);
+    }
+
+    public void setAll(Collection<T> cells) {
+        // update bitset
+        selectedCellBitSetMap.clear();
+        for (T tp : cells) {
+            final int row = tp.getRow();
+            final int columnIndex = tp.getColumn();
+
+            // update the bitset map
+            BitSet bitset;
+            if (! selectedCellBitSetMap.containsKey(row)) {
+                bitset = new BitSet();
+                selectedCellBitSetMap.put(row, bitset);
+            } else {
+                bitset = selectedCellBitSetMap.get(row);
+            }
+
+            if (columnIndex < 0) {
+                continue;
+            }
+
+            bitset.set(columnIndex);
+        }
+
+        // add into the list
+        selectedCells.setAll(cells);
+    }
+
+    public void remove(T tp) {
+        final int row = tp.getRow();
+        final int columnIndex = tp.getColumn();
+
+        // update the bitset map
+        if (selectedCellBitSetMap.containsKey(row)) {
+            BitSet bitset = selectedCellBitSetMap.get(row);
+
+            if (columnIndex >= 0) {
+                bitset.clear(columnIndex);
+            }
+
+            if (bitset.isEmpty()) {
+                selectedCellBitSetMap.remove(row);
+            }
+        }
+
+        // update list
+        selectedCells.remove(tp);
+    }
+
+    public void clear() {
+        // update bitset
+        selectedCellBitSetMap.clear();
+
+        // update list
+        selectedCells.clear();
+    }
+
+    public boolean isSelected(int row, int columnIndex) {
+        if (columnIndex < 0) {
+            return selectedCellBitSetMap.containsKey(row);
+        } else {
+            return selectedCellBitSetMap.containsKey(row) ? selectedCellBitSetMap.get(row).get(columnIndex) : false;
+        }
+    }
+
+    public int indexOf(T tp) {
+        return sortedSelectedCells.indexOf(tp);
+    }
+
+    public boolean isEmpty() {
+        return selectedCells.isEmpty();
+    }
+
+    public ObservableList<T> getSelectedCells() {
+        return selectedCells;
+    }
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/SpreadsheetGridView.java b/src/impl/org/controlsfx/spreadsheet/SpreadsheetGridView.java
new file mode 100644
index 0000000000000000000000000000000000000000..53f9fe9119138623e45a53968a793dbf5676fdb6
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/SpreadsheetGridView.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2013, 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+import javafx.scene.control.TableView;
+import javafx.scene.input.MouseEvent;
+
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+public class SpreadsheetGridView extends TableView<ObservableList<SpreadsheetCell>> {
+    private final SpreadsheetHandle handle;
+
+    /*
+     * cache the stylesheet as lookup takes time and the getUserAgentStylesheet is called repeatedly
+     */
+    private String stylesheet;
+
+    /**
+     * We don't want to show the current value in the TextField when we are
+     * editing by typing a key. We want directly to take those typed letters
+     * and put them into the textfield.
+     */
+    public SpreadsheetGridView(SpreadsheetHandle handle) {
+        this.handle = handle;
+        
+
+    }
+
+    @Override
+    public String getUserAgentStylesheet() {
+        /*
+         * For more information please see RT-40658
+         */
+        if (stylesheet == null) {
+            stylesheet = SpreadsheetView.class.getResource("spreadsheet.css") //$NON-NLS-1$
+                    .toExternalForm();
+        }
+
+        return stylesheet;
+    }
+
+    @Override
+    protected javafx.scene.control.Skin<?> createDefaultSkin() {
+        return new GridViewSkin(handle);
+    }
+
+    public GridViewSkin getGridViewSkin() {
+        return handle.getCellsViewSkin();
+    }
+};
diff --git a/src/impl/org/controlsfx/spreadsheet/SpreadsheetHandle.java b/src/impl/org/controlsfx/spreadsheet/SpreadsheetHandle.java
new file mode 100644
index 0000000000000000000000000000000000000000..474f0090ce9aeeecdd2f3c6384e4c1f18aaaf5ab
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/SpreadsheetHandle.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package impl.org.controlsfx.spreadsheet;
+
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+/**
+ * Implementation vs public bridge.
+ */
+public abstract class SpreadsheetHandle {
+	/** Access the main control. */
+	protected abstract SpreadsheetView getView();
+	/** Accesses the grid (ie cell table) in the spreadsheet. */
+	protected abstract SpreadsheetGridView getGridView();
+	/** Accesses the grid view (ie cell table view). */
+	protected abstract GridViewSkin getCellsViewSkin();
+        /** Whether that column width has been set by the user. */
+        protected abstract boolean isColumnWidthSet(int indexColumn);
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/TableViewSpanSelectionModel.java b/src/impl/org/controlsfx/spreadsheet/TableViewSpanSelectionModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2b585bae163cd04d0a5343c196b25f6a6b3fbee
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/TableViewSpanSelectionModel.java
@@ -0,0 +1,912 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import com.sun.javafx.collections.MappingChange;
+import com.sun.javafx.collections.NonIterableChange;
+import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import javafx.animation.KeyFrame;
+import javafx.animation.Timeline;
+import javafx.beans.InvalidationListener;
+import javafx.beans.NamedArg;
+import javafx.beans.Observable;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.collections.WeakListChangeListener;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.event.WeakEventHandler;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumnBase;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableView;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.util.Duration;
+import javafx.util.Pair;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+/**
+ *
+ * The Selection Model adapted for the SpreadsheetView regarding span.
+ */
+public class TableViewSpanSelectionModel extends
+        TableView.TableViewSelectionModel<ObservableList<SpreadsheetCell>>{
+
+    private boolean shift = false; // Register state of 'shift' key
+    private boolean key = false; // Register if we last touch the keyboard
+    // or the mouse
+    private boolean drag = false; // register if we are dragging (no
+    // edition)
+    private MouseEvent mouseEvent;
+    private boolean makeAtomic;
+    private SpreadsheetGridView cellsView;
+
+    private SpreadsheetView spreadsheetView;
+    // the only 'proper' internal data structure, selectedItems and
+    // selectedIndices
+    // are both 'read-only and unbacked'.
+    private final SelectedCellsMapTemp<TablePosition<ObservableList<SpreadsheetCell>, ?>> selectedCellsMap;
+
+    // we create a ReadOnlyUnbackedObservableList of selectedCells here so
+    // that we can fire custom list change events.
+    private final ReadOnlyUnbackedObservableList<TablePosition<ObservableList<SpreadsheetCell>, ?>> selectedCellsSeq;
+
+    /**
+     * We use these variable in order to stay on the same row/column when
+     * navigating with arrows. If we are going down, and we are arriving on a
+     * column-spanning cell, when going down again, we don't want to go on the
+     * starting column of the spanning cell but on the same column we arrived
+     * previously.
+     */
+    private int oldCol = -1;
+    private TableColumn oldTableColumn = null;
+    private int oldRow = -1;
+    Pair<Integer, Integer> direction;
+    private int oldColSpan = -1;
+    private int oldRowSpan = -1;
+    /**
+     * Make the tableView move when selection operating outside bounds
+     */
+    private final Timeline timer;
+
+    private final EventHandler<ActionEvent> timerEventHandler = (ActionEvent event) -> {
+        GridViewSkin skin = (GridViewSkin) getCellsViewSkin();
+        if (mouseEvent != null && !cellsView.contains(mouseEvent.getX(), mouseEvent.getY())) {
+            double sceneX = mouseEvent.getSceneX();
+            double sceneY = mouseEvent.getSceneY();
+            double layoutX = cellsView.getLayoutX();
+            double layoutY = cellsView.getLayoutY();
+            double layoutXMax = layoutX + cellsView.getWidth();
+            double layoutYMax = layoutY + cellsView.getHeight();
+
+            if (sceneX > layoutXMax) {
+                skin.getHBar().increment();
+            } else if (sceneX < layoutX) {
+                skin.getHBar().decrement();
+            }
+            if (sceneY > layoutYMax) {
+                skin.getVBar().increment();
+            } else if (sceneY < layoutY) {
+                skin.getVBar().decrement();
+            }
+        }
+    };
+    /**
+     * When the drag is over, we remove the listener and stop the timer
+     */
+    private final EventHandler<MouseEvent> dragDoneHandler = new EventHandler<MouseEvent>() {
+        @Override
+        public void handle(MouseEvent mouseEvent) {
+            drag = false;
+            timer.stop();
+            spreadsheetView.removeEventHandler(MouseEvent.MOUSE_RELEASED, this);
+        }
+    };
+
+    private final EventHandler<KeyEvent> keyPressedEventHandler = (KeyEvent keyEvent) -> {
+        key = true;
+        shift = keyEvent.isShiftDown();
+    };
+
+    private final EventHandler<MouseEvent> mousePressedEventHandler = (MouseEvent mouseEvent1) -> {
+        key = false;
+        shift = mouseEvent1.isShiftDown();
+    };
+
+    private final EventHandler<MouseEvent> onDragDetectedEventHandler = new EventHandler<MouseEvent>() {
+        @Override
+        public void handle(MouseEvent mouseEvent) {
+            cellsView.addEventHandler(MouseEvent.MOUSE_RELEASED, dragDoneHandler);
+            drag = true;
+            timer.setCycleCount(Timeline.INDEFINITE);
+            timer.play();
+        }
+    };
+
+    private final EventHandler<MouseEvent> onMouseDragEventHandler = (MouseEvent e) -> {
+        mouseEvent = e;
+    };
+
+    private final ListChangeListener<TablePosition<ObservableList<SpreadsheetCell>, ?>> listChangeListener = this::handleSelectedCellsListChangeEvent;
+
+    /**
+     * *********************************************************************
+     *
+     * Constructors
+     *
+     *********************************************************************
+     */
+    /**
+     * Constructor
+     * @param spreadsheetView
+     * @param cellsView
+     */
+    public TableViewSpanSelectionModel(@NamedArg("spreadsheetView") SpreadsheetView spreadsheetView, @NamedArg("cellsView") SpreadsheetGridView cellsView) {
+        super(cellsView);
+        this.cellsView = cellsView;
+        this.spreadsheetView = spreadsheetView;
+
+        timer = new Timeline(new KeyFrame(Duration.millis(100), new WeakEventHandler<>((timerEventHandler))));
+        cellsView.addEventHandler(KeyEvent.KEY_PRESSED, new WeakEventHandler<>(keyPressedEventHandler));
+
+        cellsView.addEventFilter(MouseEvent.MOUSE_PRESSED, new WeakEventHandler<>(mousePressedEventHandler));
+        cellsView.setOnDragDetected(new WeakEventHandler<>(onDragDetectedEventHandler));
+
+        cellsView.setOnMouseDragged(new WeakEventHandler<>(onMouseDragEventHandler));
+
+        selectedCellsMap = new SelectedCellsMapTemp<>(new WeakListChangeListener<>(listChangeListener));
+
+        selectedCellsSeq = new ReadOnlyUnbackedObservableList<TablePosition<ObservableList<SpreadsheetCell>, ?>>() {
+            @Override
+            public TablePosition<ObservableList<SpreadsheetCell>, ?> get(int i) {
+                return selectedCellsMap.get(i);
+            }
+
+            @Override
+            public int size() {
+                return selectedCellsMap.size();
+            }
+        };
+    }
+
+    private void handleSelectedCellsListChangeEvent(
+            ListChangeListener.Change<? extends TablePosition<ObservableList<SpreadsheetCell>, ?>> c) {
+        if (makeAtomic) {
+            return;
+        }
+
+        selectedCellsSeq.callObservers(new MappingChange<>(c, MappingChange.NOOP_MAP, selectedCellsSeq));
+        c.reset();
+    }
+
+    /**
+     * *********************************************************************
+     * * Public selection API * *
+     * ********************************************************************
+     */
+    private TablePosition<ObservableList<SpreadsheetCell>, ?> old = null;
+
+    @Override
+    public void select(int row, TableColumn<ObservableList<SpreadsheetCell>, ?> column) {
+        if (row < 0 || row >= getItemCount()) {
+            return;
+        }
+
+        // if I'm in cell selection mode but the column is null, I don't
+        // want
+        // to select the whole row instead...
+        if (isCellSelectionEnabled() && column == null) {
+            return;
+        }
+        // Variable we need for algorithm
+        TablePosition<ObservableList<SpreadsheetCell>, ?> posFinal = new TablePosition<>(getTableView(), row,
+                column);
+
+        final SpreadsheetView.SpanType spanType = spreadsheetView.getSpanType(row, posFinal.getColumn());
+
+        /**
+         * We check if we are on covered cell. If so we have the algorithm of
+         * the focus model to give the selection to the right cell.
+         *
+         */
+        switch (spanType) {
+            case ROW_SPAN_INVISIBLE:
+                /**
+                 * If we notice that the new selected cell is the previous one,
+                 * then it means that we were already on the cell and we wanted
+                 * to go below. We make sure that old is not null, and that the
+                 * move is initiated by keyboard. Because if it's a click, then
+                 * we just want to go on the clicked cell (not below)
+                 */
+                if (old != null && !shift && old.getColumn() == posFinal.getColumn()
+                        && old.getRow() == posFinal.getRow() - 1) {
+                    int visibleRow = FocusModelListener.getNextRowNumber(old, cellsView);
+                    /**
+                     * If the visibleRow we're targeting is out of bounds, we do
+                     * not want to get a visibleCell, so we step out. But we
+                     * need to set edition to false because we will be going
+                     * back to the old cell and we could go to edition.
+                     */
+                    if (visibleRow < getItemCount()) {
+                        posFinal = getVisibleCell(visibleRow, old.getTableColumn(), old.getColumn());
+                        break;
+                    }
+                }
+                // If the current selected cell if hidden by row span, we go
+                // above
+                posFinal = getVisibleCell(row, column, posFinal.getColumn());
+                break;
+            case BOTH_INVISIBLE:
+                // If the current selected cell if hidden by a both (row and
+                // column) span, we go left-above
+                posFinal = getVisibleCell(row, column, posFinal.getColumn());
+                break;
+            case COLUMN_SPAN_INVISIBLE:
+                // If we notice that the new selected cell is the previous one,
+                // then it means that we were
+                // already on the cell and we wanted to go right.
+                if (old != null && !shift && old.getColumn() == posFinal.getColumn() - 1
+                        && old.getRow() == posFinal.getRow()) {
+                    posFinal = getVisibleCell(old.getRow(), FocusModelListener.getTableColumnSpan(old, cellsView), getTableColumnSpanInt(old));
+                } else {
+                    // If the current selected cell if hidden by column span, we
+                    // go left
+                        posFinal = getVisibleCell(row, column, posFinal.getColumn());
+                }
+            default:
+                break;
+        }
+
+        if (direction != null && key) {
+            /**
+             * If I'm going up or down, and the previous cell had a column span,
+             * then we take the column used before instead of the current
+             * column.
+             */
+            if (direction.getKey() != 0 && oldColSpan > 1) {
+                posFinal = getVisibleCell(posFinal.getRow(), oldTableColumn, oldCol);
+            } else if (direction.getValue() != 0 && oldRowSpan > 1) {
+                posFinal = getVisibleCell(oldRow, posFinal.getTableColumn(), posFinal.getColumn());
+            }
+        }
+        old = posFinal;
+
+        //If it's a click, we register everything.
+        if (!key) {
+            oldRow = old.getRow();
+            oldCol = old.getColumn();
+            oldTableColumn = old.getTableColumn();
+        } else {
+            //If we're going up or down, we register the row changing, not the column.
+            if (direction != null && direction.getKey() != 0) {
+                oldRow = old.getRow();
+            } else if (direction != null && direction.getValue() != 0) {
+                oldCol = old.getColumn();
+                oldTableColumn = old.getTableColumn();
+            }
+        }
+        if (getSelectionMode() == SelectionMode.SINGLE) {
+            quietClearSelection();
+        }
+        SpreadsheetCell cell = cellsView.getItems().get(old.getRow()).get(old.getColumn());
+        oldRowSpan = cell.getRowSpan();
+        oldColSpan = cell.getColumnSpan();
+        for (int i = cell.getRow(); i < cell.getRowSpan() + cell.getRow(); ++i) {
+            for (int j = cell.getColumn(); j < cell.getColumnSpan() + cell.getColumn(); ++j) {
+                posFinal = new TablePosition<>(getTableView(), i, getTableView().getVisibleLeafColumn(j));
+                selectedCellsMap.add(posFinal);
+            }
+        }
+
+        updateScroll(old);
+        addSelectedRowsAndColumns(old);
+
+        setSelectedIndex(old.getRow());
+        setSelectedItem(getModelItem(old.getRow()));
+        if (getTableView().getFocusModel() == null) {
+            return;
+        }
+
+        getTableView().getFocusModel().focus(old.getRow(), old.getTableColumn());
+    }
+
+    /**
+     * We try to make visible the rows that may be hidden by Fixed rows.
+     *
+     * @param posFinal
+     */
+    private void updateScroll(TablePosition<ObservableList<SpreadsheetCell>, ?> posFinal) {
+
+        /**
+         * We don't want to do any scroll when dragging or selecting with click.
+         * Only keyboard action arrow action.
+         */
+        if (!drag && key && getCellsViewSkin().getCellsSize() != 0 && spreadsheetView.getFixedRows().size() != 0) {
+
+            int start = getCellsViewSkin().getRow(0).getIndex();
+            double posFinalOffset = 0;
+            for (int j = start; j < posFinal.getRow(); ++j) {
+                posFinalOffset += getSpreadsheetViewSkin().getRowHeight(j);
+            }
+
+            if (getCellsViewSkin().getFixedRowHeight() > posFinalOffset) {
+                cellsView.scrollTo(posFinal.getRow());
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void clearSelection(int row, TableColumn<ObservableList<SpreadsheetCell>, ?> column) {
+
+        final TablePosition<ObservableList<SpreadsheetCell>, ?> tp = new TablePosition<>(getTableView(), row,
+                column);
+        if (tp.getRow() < 0 || tp.getColumn() < 0) {
+            return;
+        }
+        List<TablePosition<ObservableList<SpreadsheetCell>, ?>> selectedCells;
+        if ((selectedCells = isSelectedRange(row, column, tp.getColumn())) != null) {
+            for (TablePosition<ObservableList<SpreadsheetCell>, ?> cell : selectedCells) {
+                selectedCellsMap.remove(cell);
+                removeSelectedRowsAndColumns(cell);
+                focus(cell.getRow());
+            }
+        } else {
+            for (TablePosition<ObservableList<SpreadsheetCell>, ?> pos : getSelectedCells()) {
+                if (pos.equals(tp)) {
+                    selectedCellsMap.remove(pos);
+                    removeSelectedRowsAndColumns(pos);
+                    // give focus to this cell index
+                    focus(row);
+                    return;
+                }
+            }
+        }
+    }
+
+    /**
+     * When we set a new grid, we need to update the selected Cells because
+     * otherwise we will end up with TablePosition which have "-1" as their
+     * column number. So we need to verify that the old selected cells are still
+     * selectable and select them.
+     *
+     * @param selectedCells
+     */
+    public void verifySelectedCells(List<Pair<Integer, Integer>> selectedCells) {
+        List<TablePosition<ObservableList<SpreadsheetCell>, ?>> newList = new ArrayList<>();
+        clearSelection();
+
+        final int itemCount = getItemCount();
+        final int columnSize = getTableView().getColumns().size();
+        final HashSet<Integer> selectedRows = new HashSet<>();
+        final HashSet<Integer> selectedColumns = new HashSet<>();
+        TablePosition<ObservableList<SpreadsheetCell>, ?> pos = null;
+        for (Pair<Integer, Integer> position : selectedCells) {
+            if (position.getKey() < 0
+                    || position.getKey() >= itemCount
+                    || position.getValue() < 0
+                    || position.getValue() >= columnSize) {
+                continue;
+            }
+
+            final TableColumn<ObservableList<SpreadsheetCell>, ?> column = getTableView().getVisibleLeafColumn(position.getValue());
+
+            pos = getVisibleCell(position.getKey(), column, position.getValue());
+            // We store all the selectedColumn and Rows, we will update
+            // just once at the end
+            final SpreadsheetCell cell = cellsView.getItems().get(pos.getRow()).get(pos.getColumn());
+            for (int i = cell.getRow(); i < cell.getRowSpan() + cell.getRow(); ++i) {
+                selectedColumns.add(i);
+                for (int j = cell.getColumn(); j < cell.getColumnSpan() + cell.getColumn(); ++j) {
+                    selectedRows.add(j);
+                    pos = new TablePosition<>(getTableView(), i, getTableView().getVisibleLeafColumn(j));
+                    newList.add(pos);
+                }
+            }
+        }
+        selectedCellsMap.setAll(newList);
+
+        final TablePosition finalPos = pos;
+        // Then we update visuals just once
+        GridViewSkin skin = getSpreadsheetViewSkin();
+        //If the skin is null, we just wait till everything is ready..
+        if (skin == null) {
+            cellsView.skinProperty().addListener(new InvalidationListener() {
+
+                @Override
+                public void invalidated(Observable observable) {
+                    cellsView.skinProperty().removeListener(this);
+                    GridViewSkin skin = getSpreadsheetViewSkin();
+                    if (skin != null) {
+                        updateSelectedVisuals(skin, finalPos, selectedRows, selectedColumns);
+                    }
+                }
+            });
+        } else {
+            updateSelectedVisuals(skin, pos, selectedRows, selectedColumns);
+        }
+    }
+
+    /**
+     * When all the selection has been made, we just need to light up the
+     * indicators that are showing which indexes are selected.
+     *
+     * @param skin
+     * @param pos
+     * @param selectedRows
+     * @param selectedColumns
+     */
+    private void updateSelectedVisuals(GridViewSkin skin, TablePosition pos, HashSet<Integer> selectedRows, HashSet<Integer> selectedColumns) {
+        if (skin != null) {
+            skin.getSelectedRows().addAll(selectedColumns);
+            skin.getSelectedColumns().addAll(selectedRows);
+        }
+
+        /**
+         * If we made some selection, we need to force the visual selected
+         * confirmation to come when the layout is starting. Doing it before
+         * will result in a selected cell with no css applied to it.
+         */
+        if (pos != null) {
+            getCellsViewSkin().lastRowLayout.set(true);
+            getCellsViewSkin().lastRowLayout.addListener(new InvalidationListener() {
+
+                @Override
+                public void invalidated(Observable observable) {
+                    handleSelectedCellsListChangeEvent(new NonIterableChange.SimpleAddChange<>(0,
+                            selectedCellsMap.size(), selectedCellsSeq));
+                    getCellsViewSkin().lastRowLayout.removeListener(this);
+                }
+            });
+        }
+    }
+
+    @Override
+    public void selectRange(int minRow, TableColumnBase<ObservableList<SpreadsheetCell>, ?> minColumn, int maxRow,
+            TableColumnBase<ObservableList<SpreadsheetCell>, ?> maxColumn) {
+
+        if (getSelectionMode() == SelectionMode.SINGLE) {
+            quietClearSelection();
+            select(maxRow, maxColumn);
+            return;
+        }
+        SpreadsheetCell cell;
+
+        makeAtomic = true;
+
+        final int itemCount = getItemCount();
+
+        final int minColumnIndex = getTableView().getVisibleLeafIndex(
+                (TableColumn<ObservableList<SpreadsheetCell>, ?>) minColumn);
+        final int maxColumnIndex = getTableView().getVisibleLeafIndex(
+                (TableColumn<ObservableList<SpreadsheetCell>, ?>) maxColumn);
+        final int _minColumnIndex = Math.min(minColumnIndex, maxColumnIndex);
+        final int _maxColumnIndex = Math.max(minColumnIndex, maxColumnIndex);
+
+        final int _minRow = Math.min(minRow, maxRow);
+        final int _maxRow = Math.max(minRow, maxRow);
+
+        HashSet<Integer> selectedRows = new HashSet<>();
+        HashSet<Integer> selectedColumns = new HashSet<>();
+
+        for (int _row = _minRow; _row <= _maxRow; _row++) {
+            for (int _col = _minColumnIndex; _col <= _maxColumnIndex; _col++) {
+                // begin copy/paste of select(int, column) method (with some
+                // slight modifications)
+                if (_row < 0 || _row >= itemCount) {
+                    continue;
+                }
+
+                final TableColumn<ObservableList<SpreadsheetCell>, ?> column = getTableView().getVisibleLeafColumn(
+                        _col);
+
+                // if I'm in cell selection mode but the column is null, I
+                // don't want
+                // to select the whole row instead...
+                if (column == null) {
+                    continue;
+                }
+
+                TablePosition<ObservableList<SpreadsheetCell>, ?> pos = getVisibleCell(_row, column, _col);
+
+                // We store all the selectedColumn and Rows, we will update
+                // just once at the end
+                cell = cellsView.getItems().get(pos.getRow()).get(pos.getColumn());
+                for (int i = cell.getRow(); i < cell.getRowSpan() + cell.getRow(); ++i) {
+                    selectedColumns.add(i);
+                    for (int j = cell.getColumn(); j < cell.getColumnSpan() + cell.getColumn(); ++j) {
+                        selectedRows.add(j);
+                        pos = new TablePosition<>(getTableView(), i, getTableView().getVisibleLeafColumn(j));
+                        selectedCellsMap.add(pos);
+                    }
+                }
+
+//                makeAtomic = true;
+                // end copy/paste
+            }
+        }
+        makeAtomic = false;
+
+        // Then we update visuals just once
+        getSpreadsheetViewSkin().getSelectedRows().addAll(selectedColumns);
+        getSpreadsheetViewSkin().getSelectedColumns().addAll(selectedRows);
+
+        // fire off events
+        setSelectedIndex(maxRow);
+        setSelectedItem(getModelItem(maxRow));
+        if (getTableView().getFocusModel() == null) {
+            return;
+        }
+
+        //FIXME Focus is wrong, and endIndex also..
+        getTableView().getFocusModel().focus(maxRow, (TableColumn<ObservableList<SpreadsheetCell>, ?>) maxColumn);
+
+        /**
+         * If we end up on a spanned cell, there is not reliable way to
+         * determine which is the last index, certainly not the maxRow and
+         * maxColumn. So right now we need to take this extreme measure in order
+         * to be sure that the cells will be highlighted correctly.
+         */
+        final int startChangeIndex = selectedCellsMap.indexOf(new TablePosition<>(getTableView(), minRow,
+                (TableColumn<ObservableList<SpreadsheetCell>, ?>) minColumn));
+        final int endChangeIndex = selectedCellsMap.getSelectedCells().size() - 1;//indexOf(new TablePosition<>(getTableView(), maxRow,
+//                (TableColumn<ObservableList<SpreadsheetCell>, ?>) maxColumn));
+
+        if (startChangeIndex > -1 && endChangeIndex > -1) {
+            final int startIndex = Math.min(startChangeIndex, endChangeIndex);
+            final int endIndex = Math.max(startChangeIndex, endChangeIndex);
+            handleSelectedCellsListChangeEvent(new NonIterableChange.SimpleAddChange<>(startIndex,
+                    endIndex + 1, selectedCellsSeq));
+        }
+    }
+
+    @Override
+    public void selectAll() {
+        if (getSelectionMode() == SelectionMode.SINGLE) {
+            return;
+        }
+
+        quietClearSelection();
+
+        List<TablePosition<ObservableList<SpreadsheetCell>, ?>> indices = new ArrayList<>();
+        TableColumn<ObservableList<SpreadsheetCell>, ?> column;
+        TablePosition<ObservableList<SpreadsheetCell>, ?> tp = null;
+
+        for (int col = 0; col < getTableView().getVisibleLeafColumns().size(); col++) {
+            column = getTableView().getVisibleLeafColumns().get(col);
+            for (int row = 0; row < getItemCount(); row++) {
+                tp = new TablePosition<>(getTableView(), row, column);
+                indices.add(tp);
+            }
+        }
+        selectedCellsMap.setAll(indices);
+
+        // Then we update visuals just once
+        ArrayList<Integer> selectedColumns = new ArrayList<>();
+        for (int col = 0; col < spreadsheetView.getGrid().getColumnCount(); col++) {
+            selectedColumns.add(col);
+        }
+
+        ArrayList<Integer> selectedRows = new ArrayList<>();
+        for (int row = 0; row < spreadsheetView.getGrid().getRowCount(); row++) {
+            selectedRows.add(row);
+        }
+        getSpreadsheetViewSkin().getSelectedRows().addAll(selectedRows);
+        getSpreadsheetViewSkin().getSelectedColumns().addAll(selectedColumns);
+
+        if (tp != null) {
+            select(tp.getRow(), tp.getTableColumn());
+            //Just like verticalHeader, the focus should be put on the 
+            //first cell to ease copy/paste operation.
+            getTableView().getFocusModel().focus(0, getTableView().getColumns().get(0));
+        }
+    }
+
+    @Override
+    public boolean isSelected(int row, TableColumn<ObservableList<SpreadsheetCell>, ?> column) {
+        // When in cell selection mode, we currently do NOT support
+        // selecting
+        // entire rows, so a isSelected(row, null)
+        // should always return false.
+        if (column == null || row < 0) {
+            return false;
+        }
+
+        int columnIndex = getTableView().getVisibleLeafIndex(column);
+
+        if (getCellsViewSkin().getCellsSize() != 0) {
+            TablePosition<ObservableList<SpreadsheetCell>, ?> posFinal = getVisibleCell(row, column, columnIndex);
+            return selectedCellsMap.isSelected(posFinal.getRow(), posFinal.getColumn());
+        } else {
+            return selectedCellsMap.isSelected(row, columnIndex);
+        }
+    }
+
+    /**
+     * Return the tablePosition of a selected cell inside a spanned cell if any.
+     *
+     * @param row
+     * @param column
+     * @param col
+     * @return
+     */
+    public List<TablePosition<ObservableList<SpreadsheetCell>, ?>> isSelectedRange(int row,
+            TableColumn<ObservableList<SpreadsheetCell>, ?> column, int col) {
+
+        if (col < 0 || row < 0) {
+            return null;
+        }
+
+        final SpreadsheetCell cellSpan = cellsView.getItems().get(row).get(col);
+        final int infRow = cellSpan.getRow();
+        final int supRow = infRow + cellSpan.getRowSpan();
+
+        final int infCol = cellSpan.getColumn();
+        final int supCol = infCol + cellSpan.getColumnSpan();
+        List<TablePosition<ObservableList<SpreadsheetCell>, ?>> selectedCells = new ArrayList<>();
+        for (final TablePosition<ObservableList<SpreadsheetCell>, ?> tp : getSelectedCells()) {
+            if (tp.getRow() >= infRow && tp.getRow() < supRow && tp.getColumn() >= infCol
+                    && tp.getColumn() < supCol) {
+                selectedCells.add(tp);
+            }
+        }
+        return selectedCells.isEmpty()? null : selectedCells;
+    }
+
+    /**
+     * *********************************************************************
+     * * Support code * *
+     * ********************************************************************
+     */
+    private void addSelectedRowsAndColumns(TablePosition<?, ?> position) {
+        GridViewSkin skin = getSpreadsheetViewSkin();
+        if (skin == null) {
+            return;
+        }
+        final SpreadsheetCell cell = cellsView.getItems().get(position.getRow()).get(position.getColumn());
+        for (int i = cell.getRow(); i < cell.getRowSpan() + cell.getRow(); ++i) {
+            skin.getSelectedRows().add(i);
+            for (int j = cell.getColumn(); j < cell.getColumnSpan() + cell.getColumn(); ++j) {
+                skin.getSelectedColumns().add(j);
+            }
+        }
+    }
+
+    private void removeSelectedRowsAndColumns(TablePosition<?, ?> position) {
+        final SpreadsheetCell cell = cellsView.getItems().get(position.getRow()).get(position.getColumn());
+        for (int i = cell.getRow(); i < cell.getRowSpan() + cell.getRow(); ++i) {
+            getSpreadsheetViewSkin().getSelectedRows().remove(Integer.valueOf(i));
+            for (int j = cell.getColumn(); j < cell.getColumnSpan() + cell.getColumn(); ++j) {
+                getSpreadsheetViewSkin().getSelectedColumns().remove(Integer.valueOf(j));
+            }
+        }
+    }
+
+    @Override
+    public void clearAndSelect(int row, TableColumn<ObservableList<SpreadsheetCell>, ?> column) {
+            // RT-33558 if this method has been called with a given row/column
+        // intersection, and that row/column intersection is the only
+        // selection currently, then this method becomes a no-op.
+
+        // This is understandable but not compatible with spanning
+        // selection.
+            /*
+         * if (getSelectedCells().size() == 1 && isSelected(row, column)) {
+         * return; }
+         */
+        makeAtomic = true;
+        // firstly we make a copy of the selection, so that we can send out
+        // the correct details in the selection change event
+        List<TablePosition<ObservableList<SpreadsheetCell>, ?>> previousSelection = new ArrayList<>(
+                selectedCellsMap.getSelectedCells());
+
+        // then clear the current selection
+        clearSelection();
+
+        // and select the new row
+        select(row, column);
+
+        makeAtomic = false;
+
+        // fire off a single add/remove/replace notification (rather than
+        // individual remove and add notifications) - see RT-33324
+        if (old != null && old.getColumn() >= 0) {
+            TableColumn<ObservableList<SpreadsheetCell>, ?> columnFinal = getTableView().getColumns().get(
+                    old.getColumn());
+            int changeIndex = selectedCellsSeq.indexOf(new TablePosition<>(getTableView(), old.getRow(),
+                    columnFinal));
+            NonIterableChange.GenericAddRemoveChange<TablePosition<ObservableList<SpreadsheetCell>, ?>> change = new NonIterableChange.GenericAddRemoveChange<>(
+                    changeIndex, changeIndex + 1, previousSelection, selectedCellsSeq);
+            handleSelectedCellsListChangeEvent(change);
+        }
+    }
+
+    /**
+     * FIXME I don't understand why TablePosition is not parameterized in the
+     * API..
+     *
+     * @return
+     */
+    @Override
+    public ObservableList<TablePosition> getSelectedCells() {
+        return (ObservableList<TablePosition>) (Object) selectedCellsSeq;
+    }
+
+    @Override
+    public void selectAboveCell() {
+        final TablePosition<ObservableList<SpreadsheetCell>, ?> pos = getFocusedCell();
+        if (pos.getRow() == -1) {
+            select(getItemCount() - 1);
+        } else if (pos.getRow() > 0) {
+            select(pos.getRow() - 1, pos.getTableColumn());
+        }
+
+    }
+
+    @Override
+    public void selectBelowCell() {
+        final TablePosition<ObservableList<SpreadsheetCell>, ?> pos = getFocusedCell();
+
+        if (pos.getRow() == -1) {
+            select(0);
+        } else if (pos.getRow() < getItemCount() - 1) {
+            select(pos.getRow() + 1, pos.getTableColumn());
+        }
+
+    }
+
+    @Override
+    public void selectLeftCell() {
+        if (!isCellSelectionEnabled()) {
+            return;
+        }
+
+        final TablePosition<ObservableList<SpreadsheetCell>, ?> pos = getFocusedCell();
+        if (pos.getColumn() - 1 >= 0) {
+            select(pos.getRow(), getTableColumn(pos.getTableColumn(), -1));
+        }
+
+    }
+
+    @Override
+    public void selectRightCell() {
+        if (!isCellSelectionEnabled()) {
+            return;
+        }
+
+        final TablePosition<ObservableList<SpreadsheetCell>, ?> pos = getFocusedCell();
+        if (pos.getColumn() + 1 < getTableView().getVisibleLeafColumns().size()) {
+            select(pos.getRow(), getTableColumn(pos.getTableColumn(), 1));
+        }
+
+    }
+
+    @Override
+    public void clearSelection() {
+        if (!makeAtomic) {
+            setSelectedIndex(-1);
+            setSelectedItem(getModelItem(-1));
+            focus(-1);
+        }
+        quietClearSelection();
+    }
+
+    private void quietClearSelection() {
+        selectedCellsMap.clear();
+        GridViewSkin skin = getSpreadsheetViewSkin();
+        if (skin != null) {
+            skin.getSelectedRows().clear();
+            skin.getSelectedColumns().clear();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private TablePosition<ObservableList<SpreadsheetCell>, ?> getFocusedCell() {
+        if (getTableView().getFocusModel() == null) {
+            return new TablePosition<>(getTableView(), -1, null);
+        }
+        return (TablePosition<ObservableList<SpreadsheetCell>, ?>) cellsView.getFocusModel().getFocusedCell();
+    }
+
+    private TableColumn<ObservableList<SpreadsheetCell>, ?> getTableColumn(
+            TableColumn<ObservableList<SpreadsheetCell>, ?> column, int offset) {
+        final int columnIndex = getTableView().getVisibleLeafIndex(column);
+        final int newColumnIndex = columnIndex + offset;
+        return getTableView().getVisibleLeafColumn(newColumnIndex);
+    }
+
+    private GridViewSkin getSpreadsheetViewSkin() {
+        return (GridViewSkin) getCellsViewSkin();
+    }
+
+    /**
+     * For a position, return the Visible Cell associated with It can be the top
+     * of the span cell if it's visible, or it can be the first row visible if
+     * we have scrolled
+     *
+     * @param row
+     * @param column
+     * @param col
+     * @return
+     */
+    private TablePosition<ObservableList<SpreadsheetCell>, ?> getVisibleCell(int row,
+            TableColumn<ObservableList<SpreadsheetCell>, ?> column, int col) {
+        final SpreadsheetView.SpanType spanType = spreadsheetView.getSpanType(row, col);
+        switch (spanType) {
+            case NORMAL_CELL:
+            case ROW_VISIBLE:
+                return new TablePosition<>(cellsView, row, column);
+            case BOTH_INVISIBLE:
+            case COLUMN_SPAN_INVISIBLE:
+            case ROW_SPAN_INVISIBLE:
+            default:
+                final SpreadsheetCell cellSpan = cellsView.getItems().get(row).get(col);
+                if (getCellsViewSkin() == null || (getCellsViewSkin().getCellsSize() != 0 && getNonFixedRow(0).getIndex() <= cellSpan.getRow())) {
+                    return new TablePosition<>(cellsView, cellSpan.getRow(), cellsView.getColumns().get(
+                            cellSpan.getColumn()));
+                } else { // If it's not, then it's the firstkey
+                    return new TablePosition<>(cellsView, getNonFixedRow(0).getIndex(), cellsView.getColumns().get(
+                            cellSpan.getColumn()));
+                }
+        }
+    }
+
+    /**
+     * @return the inner table view skin
+     */
+    final GridViewSkin getCellsViewSkin() {
+        return (GridViewSkin) (cellsView.getSkin());
+    }
+
+    /**
+     * Return the {@link GridRow} at the specified index
+     *
+     * @param index
+     * @return
+     */
+    private GridRow getNonFixedRow(int index) {
+        return getCellsViewSkin().getRow(index);
+    }
+
+    /**
+     * Return the TableColumn right after the current TablePosition (including
+     * the ColumSpan to be on a visible Cell)
+     *
+     * @param t the current TablePosition
+     * @return
+     */
+    private int getTableColumnSpanInt(final TablePosition<?, ?> t) {
+        return t.getColumn() + cellsView.getItems().get(t.getRow()).get(t.getColumn()).getColumnSpan();
+    }
+
+}
diff --git a/src/impl/org/controlsfx/spreadsheet/VerticalHeader.java b/src/impl/org/controlsfx/spreadsheet/VerticalHeader.java
new file mode 100644
index 0000000000000000000000000000000000000000..0cefc9ebbdfb4d0c4b3b18597021c4b582309584
--- /dev/null
+++ b/src/impl/org/controlsfx/spreadsheet/VerticalHeader.java
@@ -0,0 +1,675 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.spreadsheet;
+
+import static impl.org.controlsfx.i18n.Localization.asKey;
+import static impl.org.controlsfx.i18n.Localization.localize;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Stack;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ReadOnlyDoubleProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.geometry.NodeOrientation;
+import javafx.scene.Cursor;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.Label;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.ScrollBar;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView.TableViewSelectionModel;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.StackPane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.stage.WindowEvent;
+import org.controlsfx.control.spreadsheet.Picker;
+import org.controlsfx.control.spreadsheet.SpreadsheetCell;
+import org.controlsfx.control.spreadsheet.SpreadsheetView;
+
+/**
+ * Display the vertical header on the left of the cells (view), the index of the
+ * lines displayed on screen.
+ */
+public class VerticalHeader extends StackPane {
+
+    public static final int PICKER_SIZE = 16;
+    private static final int DRAG_RECT_HEIGHT = 5;
+    private static final String TABLE_ROW_KEY = "TableRow"; //$NON-NLS-1$
+    private static final String PICKER_INDEX = "PickerIndex"; //$NON-NLS-1$
+    private static final String TABLE_LABEL_KEY = "Label"; //$NON-NLS-1$
+    private static final Image pinImage = new Image(SpreadsheetView.class.getResource("pinSpreadsheetView.png").toExternalForm()); //$NON-NLS-1$
+
+    /**
+     * *************************************************************************
+     * * Private Fields * *
+     * ************************************************************************
+     */
+    private final SpreadsheetHandle handle;
+    private final SpreadsheetView spreadsheetView;
+    private double horizontalHeaderHeight;
+    /**
+     * This represents the VerticalHeader width. It's the total amount of space
+     * used by the VerticalHeader. It's composed of the sum of the
+     * SpreadsheetView {@link SpreadsheetView#getRowHeaderWidth() } and the size
+     * of the pickers (which is fixed right now).
+     *
+     */
+    private final DoubleProperty innerVerticalHeaderWidth = new SimpleDoubleProperty();
+    private Rectangle clip; // Ensure that children do not go out of bounds
+    private ContextMenu blankContextMenu;
+
+    // used for column resizing
+    private double lastY = 0.0F;
+    private static double dragAnchorY = 0.0;
+
+    // drag rectangle overlays
+    private final List<Rectangle> dragRects = new ArrayList<>();
+
+    private final List<Label> labelList = new ArrayList<>();
+    private GridViewSkin skin;
+    private boolean resizing = false;
+
+    private final Stack<Label> pickerPile;
+    private final Stack<Label> pickerUsed;
+    
+    /**
+     * This BitSet keeps track of the selected rows (when clicked on their
+     * header) in order to allow multi-resize.
+     */
+    private final BitSet selectedRows = new BitSet();
+
+    /**
+     * ****************************************************************
+     * CONSTRUCTOR
+     *
+     * @param handle
+     * ***************************************************************
+     */
+    public VerticalHeader(final SpreadsheetHandle handle) {
+        this.handle = handle;
+        this.spreadsheetView = handle.getView();
+        pickerPile = new Stack<>();
+        pickerUsed = new Stack<>();
+    }
+
+    /**
+     * *************************************************************************
+     * * Private/Protected Methods *
+     * ***********************************************************************
+     */
+    /**
+     * Init
+     *
+     * @param skin
+     * @param horizontalHeader
+     */
+    void init(final GridViewSkin skin, HorizontalHeader horizontalHeader) {
+        this.skin = skin;
+        // Adjust position upon HorizontalHeader height
+        horizontalHeader.heightProperty().addListener(new ChangeListener<Number>() {
+            @Override
+            public void changed(ObservableValue<? extends Number> arg0, Number oldHeight, Number newHeight) {
+                horizontalHeaderHeight = newHeight.doubleValue();
+                requestLayout();
+            }
+        });
+
+        // When the Grid is changing, we need to update our information.
+        handle.getView().gridProperty().addListener(layout);
+
+        // Clip property to stay within bounds
+        clip = new Rectangle(getVerticalHeaderWidth(), snapSize(skin.getSkinnable().getHeight()));
+        clip.relocate(snappedTopInset(), snappedLeftInset());
+        clip.setSmooth(false);
+        clip.heightProperty().bind(skin.getSkinnable().heightProperty());
+        clip.widthProperty().bind(innerVerticalHeaderWidth);
+        VerticalHeader.this.setClip(clip);
+
+        // We desactivate and activate the verticalHeader upon request
+        spreadsheetView.showRowHeaderProperty().addListener(layout);
+
+        // When the Column header is showing or not, we need to update the
+        // position of the verticalHeader
+        spreadsheetView.showColumnHeaderProperty().addListener(layout);
+        spreadsheetView.getFixedRows().addListener(layout);
+        spreadsheetView.fixingRowsAllowedProperty().addListener(layout);
+        spreadsheetView.rowHeaderWidthProperty().addListener(layout);
+
+        // In case we resize the view in any manners
+        spreadsheetView.heightProperty().addListener(layout);
+
+        //When rowPickers is changing
+        spreadsheetView.getRowPickers().addListener(layout);
+
+        // For layout properly the verticalHeader when there are some selected
+        // items
+        skin.getSelectedRows().addListener(layout);
+
+        blankContextMenu = new ContextMenu();
+    }
+
+    public double getVerticalHeaderWidth() {
+        return innerVerticalHeaderWidth.get();
+    }
+    
+    public ReadOnlyDoubleProperty verticalHeaderWidthProperty(){
+        return innerVerticalHeaderWidth;
+    }
+
+    public double computeHeaderWidth() {
+        double width = 0;
+        if (!spreadsheetView.getRowPickers().isEmpty()) {
+            width += PICKER_SIZE;
+        }
+        if (spreadsheetView.isShowRowHeader()) {
+            width += spreadsheetView.getRowHeaderWidth();
+        }
+        return width;
+    }
+
+    void clearSelectedRows(){
+        selectedRows.clear();
+    }
+    
+    @Override
+    protected void layoutChildren() {
+        if (resizing) {
+            return;
+        }
+        if ((spreadsheetView.isShowRowHeader() || !spreadsheetView.getRowPickers().isEmpty()) && skin.getCellsSize() > 0) {
+
+            double x = snappedLeftInset();
+            /**
+             * Pickers
+             */
+            pickerPile.addAll(pickerUsed.subList(0, pickerUsed.size()));
+            pickerUsed.clear();
+            if (!spreadsheetView.getRowPickers().isEmpty()) {
+                innerVerticalHeaderWidth.setValue(PICKER_SIZE);
+                x += PICKER_SIZE;
+            } else {
+                innerVerticalHeaderWidth.setValue(0);
+            }
+            if (spreadsheetView.isShowRowHeader()) {
+                innerVerticalHeaderWidth.setValue(getVerticalHeaderWidth() + spreadsheetView.getRowHeaderWidth());
+            }
+
+            getChildren().clear();
+
+            final int cellSize = skin.getCellsSize();
+
+            int rowCount = 0;
+            Label label;
+
+            rowCount = addVisibleRows(rowCount, x, cellSize);
+
+//            if (spreadsheetView.isShowRowHeader()) {
+                rowCount = addFixedRows(rowCount, x, cellSize);
+//            }
+            // First one blank and on top (z-order) of the others
+            if (spreadsheetView.showColumnHeaderProperty().get()) {
+                label = getLabel(rowCount++, null);
+                label.setOnMousePressed((MouseEvent event) -> {
+                    spreadsheetView.getSelectionModel().selectAll();
+                });
+                label.setText(""); //$NON-NLS-1$
+                label.resize(spreadsheetView.getRowHeaderWidth(), horizontalHeaderHeight);
+                label.layoutYProperty().unbind();
+                label.setLayoutY(0);
+                label.setLayoutX(x);
+                label.getStyleClass().clear();
+                label.setContextMenu(blankContextMenu);
+                getChildren().add(label);
+            }
+
+            ScrollBar hbar = handle.getCellsViewSkin().getHBar();
+            //FIXME handle height.
+            if (hbar.isVisible()) {
+                // Last one blank and on top (z-order) of the others
+                label = getLabel(rowCount++, null);
+                label.getProperties().put(TABLE_ROW_KEY, null);
+                label.setText(""); //$NON-NLS-1$
+                label.resize(getVerticalHeaderWidth(), hbar.getHeight());
+                label.layoutYProperty().unbind();
+                label.relocate(snappedLeftInset(), getHeight() - hbar.getHeight());
+                label.getStyleClass().clear();
+                label.setContextMenu(blankContextMenu);
+                getChildren().add(label);
+            }
+        } else {
+            getChildren().clear();
+        }
+    }
+
+    private int addFixedRows(int rowCount, double x, int cellSize) {
+        double spaceUsedByFixedRows = 0;
+        int rowIndex;
+        Label label;
+        final Set<Integer> currentlyFixedRow = handle.getCellsViewSkin().getCurrentlyFixedRow();
+        // Then we iterate over the FixedRows if any
+        if (!spreadsheetView.getFixedRows().isEmpty() && cellSize != 0) {
+            for (int j = 0; j < spreadsheetView.getFixedRows().size(); ++j) {
+
+                rowIndex = spreadsheetView.getFixedRows().get(j);
+                if (!currentlyFixedRow.contains(rowIndex)) {
+                    break;
+                }
+                double rowHeight = skin.getRowHeight(rowIndex);
+                double y = spreadsheetView.showColumnHeaderProperty().get() ? snappedTopInset() + horizontalHeaderHeight + spaceUsedByFixedRows
+                        : snappedTopInset() + spaceUsedByFixedRows;
+                
+                if (spreadsheetView.getRowPickers().containsKey(rowIndex)) {
+                    Label picker = getPicker(spreadsheetView.getRowPickers().get(rowIndex));
+                    picker.resize(PICKER_SIZE, rowHeight);
+                    picker.layoutYProperty().unbind();
+                    picker.setLayoutY(y);
+                    getChildren().add(picker);
+                }
+                if (spreadsheetView.isShowRowHeader()) {
+                    label = getLabel(rowCount++, rowIndex);
+                    GridRow row = skin.getRowIndexed(rowIndex);
+                    label.getProperties().put(TABLE_ROW_KEY, row);
+                    label.setText(getRowHeader(rowIndex));
+                    label.resize(spreadsheetView.getRowHeaderWidth(), rowHeight);
+                    label.setContextMenu(getRowContextMenu(rowIndex));
+                    if(row != null){
+                        label.layoutYProperty().bind(row.layoutYProperty().add(horizontalHeaderHeight).add(row.verticalShift));
+                    }
+                    label.setLayoutX(x);
+                    final ObservableList<String> css = label.getStyleClass();
+                    if (skin.getSelectedRows().contains(rowIndex)) {
+                        css.addAll("selected"); //$NON-NLS-1$
+                    } else {
+                        css.removeAll("selected"); //$NON-NLS-1$
+                    }
+                    css.addAll("fixed"); //$NON-NLS-1$
+                    getChildren().add(label);
+                    // position drag overlay to intercept row resize requests if authorized by the grid.
+                    if (spreadsheetView.getGrid().isRowResizable(rowIndex)) {
+                        Rectangle dragRect = getDragRect(rowCount++);
+                        dragRect.getProperties().put(TABLE_ROW_KEY, row);
+                        dragRect.getProperties().put(TABLE_LABEL_KEY, label);
+                        dragRect.setWidth(label.getWidth());
+                        dragRect.relocate(snappedLeftInset() + x, y + rowHeight - DRAG_RECT_HEIGHT);
+                        getChildren().add(dragRect);
+                    }
+                }
+                spaceUsedByFixedRows += skin.getRowHeight(rowIndex);
+
+                
+            }
+        }
+        return rowCount;
+    }
+
+    private int addVisibleRows(int rowCount, double x, int cellSize) {
+        int rowIndex;
+        // We add horizontalHeaderHeight because we need to
+        // take the other header into account.
+        double y = snappedTopInset();
+
+        if (spreadsheetView.showColumnHeaderProperty().get()) {
+            y += horizontalHeaderHeight;
+        }
+
+        // The Labels must be aligned with the rows
+        if (cellSize != 0) {
+            y += skin.getRow(0).getLocalToParentTransform().getTy();
+        }
+
+        Label label;
+        // We don't want to add Label if there are no rows associated with.
+        final int modelRowCount = spreadsheetView.getGrid().getRowCount();
+
+        int i = 0;
+
+        GridRow row = skin.getRow(i);
+
+        double fixedRowHeight = skin.getFixedRowHeight();
+        double rowHeaderWidth = spreadsheetView.getRowHeaderWidth();
+        double height;
+
+        // We iterate over the visibleRows
+        while (cellSize != 0 && row != null && row.getIndex() < modelRowCount) {
+            rowIndex = row.getIndex();
+            height = row.getHeight();
+            /**
+             * Picker
+             */
+            if (row.getLayoutY() >= fixedRowHeight && spreadsheetView.getRowPickers().containsKey(rowIndex)) {
+                Label picker = getPicker(spreadsheetView.getRowPickers().get(rowIndex));
+                picker.resize(PICKER_SIZE, height);
+                picker.layoutYProperty().bind(row.layoutYProperty().add(horizontalHeaderHeight));
+                getChildren().add(picker);
+            }
+
+            if (spreadsheetView.isShowRowHeader()) {
+                label = getLabel(rowCount++, rowIndex);
+                label.getProperties().put(TABLE_ROW_KEY, row);
+                label.setText(getRowHeader(rowIndex));
+                label.resize(rowHeaderWidth, height);
+                label.setLayoutX(x);
+                label.layoutYProperty().bind(row.layoutYProperty().add(horizontalHeaderHeight));
+                label.setContextMenu(getRowContextMenu(rowIndex));
+
+                getChildren().add(label);
+                // We want to highlight selected rows
+                final ObservableList<String> css = label.getStyleClass();
+                if (skin.getSelectedRows().contains(rowIndex)) {
+                    css.addAll("selected"); //$NON-NLS-1$
+                } else {
+                    css.removeAll("selected"); //$NON-NLS-1$
+                }
+                if (spreadsheetView.getFixedRows().contains(rowIndex)) {
+                    css.addAll("fixed"); //$NON-NLS-1$
+                } else {
+                    css.removeAll("fixed"); //$NON-NLS-1$
+                }
+
+                y += height;
+
+                // position drag overlay to intercept row resize requests if authorized by the grid.
+                if (spreadsheetView.getGrid().isRowResizable(rowIndex)) {
+                    Rectangle dragRect = getDragRect(rowCount++);
+                    dragRect.getProperties().put(TABLE_ROW_KEY, row);
+                    dragRect.getProperties().put(TABLE_LABEL_KEY, label);
+                    dragRect.setWidth(label.getWidth());
+                    dragRect.relocate(snappedLeftInset() + x, y - DRAG_RECT_HEIGHT);
+                    getChildren().add(dragRect);
+                }
+            }
+            row = skin.getRow(++i);
+        }
+        return rowCount;
+    }
+
+    private final EventHandler<MouseEvent> rectMousePressed = new EventHandler<MouseEvent>() {
+        @Override
+        public void handle(MouseEvent me) {
+
+            if (me.getClickCount() == 2 && me.isPrimaryButtonDown()) {
+                Rectangle rect = (Rectangle) me.getSource();
+                GridRow row = (GridRow) rect.getProperties().get(TABLE_ROW_KEY);
+                skin.resizeRowToFitContent(row.getIndex());
+                requestLayout();
+            } else {
+                // rather than refer to the rect variable, we just grab
+                // it from the source to prevent a small memory leak.
+                dragAnchorY = me.getSceneY();
+                resizing = true;
+            }
+            me.consume();
+        }
+    };
+
+    private final EventHandler<MouseEvent> rectMouseDragged = new EventHandler<MouseEvent>() {
+        @Override
+        public void handle(MouseEvent me) {
+            Rectangle rect = (Rectangle) me.getSource();
+            GridRow row = (GridRow) rect.getProperties().get(TABLE_ROW_KEY);
+            Label label = (Label) rect.getProperties().get(TABLE_LABEL_KEY);
+            if (row != null) {
+                rowResizing(row, label, me);
+            }
+            me.consume();
+        }
+    };
+
+    private void rowResizing(GridRow gridRow, Label label, MouseEvent me) {
+        double draggedY = me.getSceneY() - dragAnchorY;
+        if (gridRow.getEffectiveNodeOrientation() == NodeOrientation.RIGHT_TO_LEFT) {
+            draggedY = -draggedY;
+        }
+
+        double delta = draggedY - lastY;
+
+        Double newHeight = gridRow.getHeight() + delta;
+        if (newHeight < 0) {
+            return;
+        }
+        handle.getCellsViewSkin().rowHeightMap.put(gridRow.getIndex(), newHeight);
+        Event.fireEvent(spreadsheetView, new SpreadsheetView.RowHeightEvent(gridRow.getIndex(), newHeight));
+        label.resize(spreadsheetView.getRowHeaderWidth(), newHeight);
+        gridRow.setPrefHeight(newHeight);
+        gridRow.requestLayout();
+        
+        lastY = draggedY;
+    }
+
+    private final EventHandler<MouseEvent> rectMouseReleased = new EventHandler<MouseEvent>() {
+        @Override
+        public void handle(MouseEvent me) {
+            lastY = 0.0F;
+            resizing = false;
+            requestLayout();
+            me.consume();
+            //We resize the other selected rows if the resized one is selected.
+            Rectangle rect = (Rectangle) me.getSource();
+            GridRow row = (GridRow) rect.getProperties().get(TABLE_ROW_KEY);
+            if (selectedRows.get(row.getIndex())) {
+                double height = row.getHeight();
+                for (int i = selectedRows.nextSetBit(0); i >= 0; i = selectedRows.nextSetBit(i + 1)) {
+                    skin.rowHeightMap.put(i, height);
+                    Event.fireEvent(spreadsheetView, new SpreadsheetView.RowHeightEvent(i, height));
+                }
+            }
+        }
+    };
+
+    /**
+     * Create a new label and put it in the pile or just grab one from the pile.
+     *
+     * @param rowNumber
+     * @return
+     */
+    private Label getLabel(int rowNumber, Integer row) {
+        Label label;
+        if (labelList.isEmpty() || labelList.size() <= rowNumber) {
+            label = new Label();
+            labelList.add(label);
+        } else {
+            label = labelList.get(rowNumber);
+        }
+        // We want to select the whole row when clicking on a header.
+        label.setOnMousePressed(row == null ? null : (MouseEvent event) -> {
+            if (event.isPrimaryButtonDown()) {
+                if (event.getClickCount() == 2) {
+                    skin.resizeRowToFitContent(row);
+                    requestLayout();
+                } else {
+                    headerClicked(row, event);
+                }
+            }
+        });
+        return label;
+    }
+
+    /**
+     * If a header is clicked, we must select the whole row. If Control key of
+     * Shift key is pressed, we must not deselect the previous selection but
+     * just act like the {@link GridViewBehavior} would.
+     *
+     * @param row
+     * @param event
+     */
+    private void headerClicked(int row, MouseEvent event) {
+        TableViewSelectionModel<ObservableList<SpreadsheetCell>> sm = handle.getGridView().getSelectionModel();
+        int focusedRow = sm.getFocusedIndex();
+        int rowCount = handle.getView().getGrid().getRowCount();
+        ObservableList<TableColumn<ObservableList<SpreadsheetCell>, ?>> columns = sm.getTableView().getColumns();
+        TableColumn<ObservableList<SpreadsheetCell>, ?> firstColumn = columns.get(0);
+        TableColumn<ObservableList<SpreadsheetCell>, ?> lastColumn = columns.get(columns.size() - 1);
+
+        if (event.isShortcutDown()) {
+            BitSet tempSet = (BitSet) selectedRows.clone();
+            sm.selectRange(row, firstColumn, row, lastColumn);
+            selectedRows.or(tempSet);
+            selectedRows.set(row);
+        } else if (event.isShiftDown() && focusedRow >= 0 && focusedRow < rowCount) {
+            sm.clearSelection();
+            sm.selectRange(focusedRow, firstColumn, row, lastColumn);
+            //We want to let the focus on the focused row.
+            sm.getTableView().getFocusModel().focus(focusedRow, firstColumn);
+            int min = Math.min(row, focusedRow);
+            int max = Math.max(row, focusedRow);
+            selectedRows.set(min, max + 1);
+        } else {
+            sm.clearSelection();
+            sm.selectRange(row, firstColumn, row, lastColumn);
+            //And we want to have the focus on the first cell in order to be able to copy/paste between rows.
+            sm.getTableView().getFocusModel().focus(row, firstColumn);
+            selectedRows.set(row);
+        }
+    }
+    
+    private Label getPicker(Picker picker) {
+        Label pickerLabel;
+        if (pickerPile.isEmpty()) {
+            pickerLabel = new Label();
+            picker.getStyleClass().addListener(layout);
+            pickerLabel.setOnMouseClicked(pickerMouseEvent);
+        } else {
+            pickerLabel = pickerPile.pop();
+        }
+        pickerUsed.push(pickerLabel);
+
+        pickerLabel.getStyleClass().setAll(picker.getStyleClass());
+        pickerLabel.getProperties().put(PICKER_INDEX, picker);
+        return pickerLabel;
+    }
+
+    private final EventHandler<MouseEvent> pickerMouseEvent = new EventHandler<MouseEvent>() {
+
+        @Override
+        public void handle(MouseEvent mouseEvent) {
+            Label picker = (Label) mouseEvent.getSource();
+
+            ((Picker) picker.getProperties().get(PICKER_INDEX)).onClick();
+        }
+    };
+
+    /**
+     * Create a new Rectangle and put it in the pile or just grab one from the
+     * pile.
+     *
+     * @param rowNumber
+     * @return
+     */
+    private Rectangle getDragRect(int rowNumber) {
+        if (dragRects.isEmpty() || dragRects.size() <= rowNumber) {
+            final Rectangle rect = new Rectangle();
+            rect.setWidth(getVerticalHeaderWidth());
+            rect.setHeight(DRAG_RECT_HEIGHT);
+            rect.setFill(Color.TRANSPARENT);
+            rect.setSmooth(false);
+            rect.setOnMousePressed(rectMousePressed);
+            rect.setOnMouseDragged(rectMouseDragged);
+            rect.setOnMouseReleased(rectMouseReleased);
+            rect.setCursor(Cursor.V_RESIZE);
+            dragRects.add(rect);
+            return rect;
+        } else {
+            return dragRects.get(rowNumber);
+        }
+    }
+
+    /**
+     * Return a contextMenu for fixing a row if possible.
+     *
+     * @param row
+     * @return
+     */
+    private ContextMenu getRowContextMenu(final Integer row) {
+        if (spreadsheetView.isRowFixable(row)) {
+            final ContextMenu contextMenu = new ContextMenu();
+
+            MenuItem fixItem = new MenuItem(localize(asKey("spreadsheet.verticalheader.menu.fix"))); //$NON-NLS-1$
+            contextMenu.setOnShowing(new EventHandler<WindowEvent>() {
+
+                @Override
+                public void handle(WindowEvent event) {
+                    if (spreadsheetView.getFixedRows().contains(row)) {
+                        fixItem.setText(localize(asKey("spreadsheet.verticalheader.menu.unfix"))); //$NON-NLS-1$
+                    } else {
+                        fixItem.setText(localize(asKey("spreadsheet.verticalheader.menu.fix"))); //$NON-NLS-1$
+                    }
+                }
+            });
+            fixItem.setGraphic(new ImageView(pinImage));
+
+            fixItem.setOnAction(new EventHandler<ActionEvent>() {
+                @Override
+                public void handle(ActionEvent arg0) {
+                    if (spreadsheetView.getFixedRows().contains(row)) {
+                        spreadsheetView.getFixedRows().remove(row);
+                    } else {
+                        spreadsheetView.getFixedRows().add(row);
+                    }
+                }
+            });
+            contextMenu.getItems().add(fixItem);
+
+            return contextMenu;
+        } else {
+            return blankContextMenu;
+        }
+    }
+
+    /**
+     * Return the String header associated with this row index.
+     *
+     * @param index
+     * @return
+     */
+    private String getRowHeader(int index) {
+        return spreadsheetView.getGrid().getRowHeaders().size() > index ? spreadsheetView
+                .getGrid().getRowHeaders().get(index) : String.valueOf(index + 1);
+    }
+
+    /**
+     * *************************************************************************
+     * * Listeners * *
+     * ************************************************************************
+     */
+    private final InvalidationListener layout = (Observable arg0) -> {
+        requestLayout();
+    };
+}
diff --git a/src/impl/org/controlsfx/table/ColumnFilter.java b/src/impl/org/controlsfx/table/ColumnFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..50d79c6af886917c9c7e5d98945e54df7e648929
--- /dev/null
+++ b/src/impl/org/controlsfx/table/ColumnFilter.java
@@ -0,0 +1,308 @@
+/**
+ * Copyright (c) 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.table;
+
+import javafx.beans.Observable;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.beans.value.WeakChangeListener;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.collections.WeakListChangeListener;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.CustomMenuItem;
+import javafx.scene.control.TableColumn;
+import org.controlsfx.control.table.TableFilter;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.BiPredicate;
+
+public final class ColumnFilter<T,R> {
+    private final TableFilter<T> tableFilter;
+    private final TableColumn<T,R> tableColumn;
+
+    private final ObservableList<FilterValue<T,R>> filterValues;
+
+    private final DupeCounter<R> filterValuesDupeCounter = new DupeCounter<>(false);
+    private final DupeCounter<R> visibleValuesDupeCounter = new DupeCounter<>(false);
+    private final HashSet<R> unselectedValues = new HashSet<>();
+    private final HashMap<CellIdentity<T>,ChangeListener<R>> trackedCells = new HashMap<>();
+    
+    private boolean lastFilter = false;
+    private boolean isDirty = false;
+    private BiPredicate<String,String> searchStrategy = (inputString, subjectString) -> subjectString.contains(inputString);
+    private volatile FilterPanel filterPanel;
+
+    private boolean initialized = false;
+
+    private final ListChangeListener<T> backingListListener = lc -> {
+        while (lc.next()) {
+            if (lc.wasAdded()) {
+                lc.getAddedSubList().stream()
+                        .forEach(t -> addBackingItem(t, getTableColumn().getCellObservableValue(t)));
+            }
+            if (lc.wasRemoved()) {
+                lc.getRemoved().stream()
+                        .forEach(t -> removeBackingItem(t, getTableColumn().getCellObservableValue(t)));
+            }
+        }
+    };
+
+    private final ListChangeListener<T> itemsListener = lc -> {
+        while (lc.next()) {
+            if (lc.wasAdded()) {
+                lc.getAddedSubList().stream()
+                        .map(getTableColumn()::getCellObservableValue)
+                        .forEach(this::addVisibleItem);
+            }
+            if (lc.wasRemoved()) {
+                lc.getRemoved().stream()
+                        .map(getTableColumn()::getCellObservableValue)
+                        .forEach(this::removeVisibleItem);
+            }
+        }
+    };
+
+    private final ChangeListener<R> changeListener = (observable, oldValue, newValue) -> {
+        if (filterValuesDupeCounter.add(newValue) == 1) {
+            getFilterValues().add(new FilterValue<>(newValue,this));
+        }
+        removeValue(oldValue);
+    };
+
+    private final ListChangeListener<FilterValue<T, R>> filterValueListChangeListener = lc -> {
+        while (lc.next()) {
+            if (lc.wasRemoved()) {
+                lc.getRemoved().stream()
+                        .filter(v -> !v.selectedProperty().get())
+                        .forEach(unselectedValues::remove);
+            }
+            if (lc.wasUpdated()) {
+                int from = lc.getFrom();
+                int to = lc.getTo();
+                lc.getList().subList(from, to).forEach(v -> {
+                    isDirty = true;
+
+                    boolean value = v.selectedProperty().getValue();
+                    if (!value) {
+                        unselectedValues.add(v.getValue());
+                    } else {
+                        unselectedValues.remove(v.getValue());
+                    }
+                });
+            }
+        }
+    };
+
+    public ColumnFilter(TableFilter<T> tableFilter, TableColumn<T,R> tableColumn) {
+        this.tableFilter = tableFilter;
+        this.tableColumn = tableColumn;
+
+        this.filterValues = FXCollections.observableArrayList(cb -> new Observable[] { cb.selectedProperty()});
+        this.attachContextMenu();
+    }
+    void setFilterPanel(FilterPanel filterPanel) {
+        this.filterPanel = filterPanel;
+    }
+    FilterPanel getFilterPanel() {
+        return filterPanel;
+    }
+    public void initialize() {
+        if (!initialized) {
+            initializeListeners();
+            initializeValues();
+            initialized = true;
+        }
+    }
+    public boolean isInitialized() {
+        return initialized;
+    }
+
+    public void selectValue(Object value) {
+        filterPanel.selectValue(value);
+    }
+    public void unselectValue(Object value) {
+        filterPanel.unSelectValue(value);
+    }
+    public void selectAllValues() {
+        filterPanel.selectAllValues();
+    }
+    public void unSelectAllValues() {
+        filterPanel.unSelectAllValues();
+    }
+    public boolean wasLastFiltered() {
+        return lastFilter;
+    }
+    public boolean hasUnselections() {
+        return unselectedValues.size() != 0;
+    }
+    public void setSearchStrategy(BiPredicate<String,String> searchStrategy) {
+        this.searchStrategy = searchStrategy;
+    }
+    public BiPredicate<String,String> getSearchStrategy() {
+        return searchStrategy;
+    }
+    public boolean isFiltered() {
+        return isDirty || unselectedValues.size() > 0;
+    }
+    public boolean valueIsVisible(R value) {
+        return visibleValuesDupeCounter.get(value) > 0;
+    }
+    public void applyFilter() {
+    	tableFilter.executeFilter();
+    	lastFilter = true;
+    	tableFilter.getColumnFilters().stream().filter(c -> !c.equals(this)).forEach(c -> c.lastFilter = false);
+    	tableFilter.getColumnFilters().stream().flatMap(c -> c.filterValues.stream()).forEach(FilterValue::refreshScope);
+        isDirty = false;
+    }
+
+    public void resetAllFilters() { 
+    	tableFilter.getColumnFilters().stream().flatMap(c -> c.filterValues.stream()).forEach(fv -> fv.selectedProperty().set(true));
+    	tableFilter.resetFilter();
+    	tableFilter.getColumnFilters().stream().forEach(c -> c.lastFilter = false);
+    	tableFilter.getColumnFilters().stream().flatMap(c -> c.filterValues.stream()).forEach(FilterValue::refreshScope);
+        isDirty = false;
+    }
+
+    public ObservableList<FilterValue<T,R>> getFilterValues() {
+        return filterValues;
+    }
+
+    public TableColumn<T,R> getTableColumn() {
+        return tableColumn;
+    }
+    public TableFilter<T> getTableFilter() { 
+        return tableFilter;
+    }
+    public boolean evaluate(T item) {
+        ObservableValue<R> value = tableColumn.getCellObservableValue(item);
+
+        return unselectedValues.size() == 0
+                || !unselectedValues.contains(value.getValue());
+    }
+
+    private void initializeValues() {
+        tableFilter.getBackingList().stream()
+                .forEach(t -> addBackingItem(t, tableColumn.getCellObservableValue(t)));
+        tableFilter.getTableView().getItems().stream()
+                .map(tableColumn::getCellObservableValue).forEach(this::addVisibleItem);
+
+    }
+
+    private void addBackingItem(T item, ObservableValue<R> cellValue) {
+        if (cellValue == null) {
+            return;
+        }
+        if (filterValuesDupeCounter.add(cellValue.getValue()) == 1) {
+            filterValues.add(new FilterValue<>(cellValue.getValue(),this));
+        }
+
+        //listen to cell value and track it
+        CellIdentity<T> trackedCellValue = new CellIdentity<>(item);
+
+		ChangeListener<R> cellListener = new WeakChangeListener(changeListener);
+        cellValue.addListener(cellListener);
+        trackedCells.put(trackedCellValue,cellListener);
+    }
+    private void removeBackingItem(T item, ObservableValue<R> cellValue) {
+        if (cellValue == null) {
+            return;
+        }
+        removeValue(cellValue.getValue());
+
+        //remove listener from cell
+        ChangeListener<R> listener = trackedCells.get(new CellIdentity<>(item));
+        cellValue.removeListener(listener);
+        trackedCells.remove(new CellIdentity<>(item));
+    }
+    private void removeValue(R value) {
+        boolean removedLastDuplicate = filterValuesDupeCounter.remove(value) == 0;
+        if (removedLastDuplicate) {
+            // Remove the FilterValue associated with the value
+            FilterValue<T,R> existingFilterValue = getFilterValues().stream()
+                    .filter(fv -> Objects.equals(fv.getValue(), value)).findAny().get();
+            getFilterValues().remove(existingFilterValue);
+        }
+    }
+    private void addVisibleItem(ObservableValue<R>  cellValue) {
+        if (cellValue != null) {
+            visibleValuesDupeCounter.add(cellValue.getValue());
+        }
+    }
+    private void removeVisibleItem(ObservableValue<R>  cellValue) {
+        if (cellValue != null) {
+            visibleValuesDupeCounter.remove(cellValue.getValue());
+        }
+    }
+    private void initializeListeners() {
+        //listen to backing list and update distinct values accordingly
+        tableFilter.getBackingList().addListener(new WeakListChangeListener<T>(backingListListener));
+
+        //listen to visible items and update visible values accordingly
+        tableFilter.getTableView().getItems().addListener(new WeakListChangeListener<T>(itemsListener));
+
+        //listen to selections on filterValues
+        filterValues.addListener(new WeakListChangeListener<>(filterValueListChangeListener));
+    }
+
+    /**Leverages tableColumn's context menu to attach filter panel */
+    private void attachContextMenu() {
+
+        ContextMenu contextMenu = new ContextMenu();
+
+        CustomMenuItem item = FilterPanel.getInMenuItem(this, contextMenu);
+
+        contextMenu.getStyleClass().add("column-filter");
+        contextMenu.getItems().add(item);
+
+        tableColumn.setContextMenu(contextMenu);
+
+        contextMenu.setOnShowing(ae -> initialize());
+    }
+
+    private static final class CellIdentity<T> {
+        private final T item;
+
+        CellIdentity(T item) {
+            this.item = item;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            return this.item == ((CellIdentity<?>)other).item;
+        }
+
+        @Override
+        public int hashCode() {
+            return System.identityHashCode(item);
+        }
+    }
+}
diff --git a/src/impl/org/controlsfx/table/DupeCounter.java b/src/impl/org/controlsfx/table/DupeCounter.java
new file mode 100644
index 0000000000000000000000000000000000000000..851a6ce4e8ff14dd43e3fe5d587bce7c512602d5
--- /dev/null
+++ b/src/impl/org/controlsfx/table/DupeCounter.java
@@ -0,0 +1,52 @@
+package impl.org.controlsfx.table;
+
+import java.util.HashMap;
+import java.util.Optional;
+
+final class DupeCounter<T> {
+
+    private final HashMap<T,Integer> counts = new HashMap<>();
+    private final boolean enforceFloor;
+
+    public DupeCounter(boolean enforceFloor) {
+        this.enforceFloor = enforceFloor;
+    }
+    public int add(T value) {
+        Integer prev = counts.get(value);
+        int newVal;
+        if (prev == null) {
+            newVal = 1;
+            counts.put(value, newVal);
+        }  else {
+            newVal = prev + 1;
+            counts.put(value, newVal);
+        }
+        return newVal;
+    }
+    public int get(T value) {
+        return Optional.ofNullable(counts.get(value)).orElse(0);
+    }
+    public int remove(T value) {
+        Integer prev = counts.get(value);
+        if (prev != null && prev > 0) {
+            int newVal = prev - 1;
+            if (newVal == 0) {
+                counts.remove(value);
+            } else {
+                counts.put(value, newVal);
+            }
+            return newVal;
+        }
+        else if (enforceFloor) {
+            throw new IllegalStateException();
+        }
+        else {
+            return 0;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return counts.toString();
+    }
+}
diff --git a/src/impl/org/controlsfx/table/FilterPanel.java b/src/impl/org/controlsfx/table/FilterPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f417bac3ebaa97becea8826913e7f2e5bc05296
--- /dev/null
+++ b/src/impl/org/controlsfx/table/FilterPanel.java
@@ -0,0 +1,275 @@
+/**
+ * Copyright (c) 2015, 2016, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.table;
+
+import com.sun.javafx.scene.control.skin.NestedTableColumnHeader;
+import com.sun.javafx.scene.control.skin.TableColumnHeader;
+import com.sun.javafx.scene.control.skin.TableViewSkin;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.WeakInvalidationListener;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.WeakChangeListener;
+import javafx.collections.transformation.FilteredList;
+import javafx.collections.transformation.SortedList;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.geometry.Side;
+import javafx.scene.control.*;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.function.Supplier;
+
+
+public final class FilterPanel<T,R> extends VBox {
+
+    private final ColumnFilter<T,R> columnFilter;
+
+    private final FilteredList<FilterValue> filterList;
+    private static final String promptText = "Search...";
+    private final TextField searchBox = new TextField();
+    private boolean searchMode = false;
+    private boolean bumpedWidth = false;
+
+    private final ListView<FilterValue> checkListView;
+	
+    // This collection will reference column header listeners. References must be kept locally because weak listeners are registered
+    private final Collection<InvalidationListener> columnHeadersChangeListeners = new ArrayList();
+
+    private static final Image filterIcon = new Image("/impl/org/controlsfx/table/filter.png");
+
+    private static final Supplier<ImageView> filterImageView = () -> {
+        ImageView imageView = new ImageView(filterIcon);
+        imageView.setFitHeight(15);
+        imageView.setPreserveRatio(true);
+        return imageView;
+    };
+
+    private final ChangeListener<Skin<?>> skinListener = (w, o, n) -> {
+        // Clear references to listeners, this will (eventually) cause the WeakListeners to expire
+        columnHeadersChangeListeners.clear();
+
+        if (n instanceof TableViewSkin) {
+            TableViewSkin<?> skin = (TableViewSkin<?>) n;
+            checkChangeContextMenu(skin, getColumnFilter().getTableColumn(), this);
+        }
+    };
+
+    void selectAllValues() {
+        checkListView.getItems().stream()
+                .forEach(item -> item.selectedProperty().set(true));
+    }
+    void unSelectAllValues() {
+        checkListView.getItems().stream()
+                .forEach(item -> item.selectedProperty().set(false));
+    }
+    void selectValue(Object value) {
+        checkListView.getItems().stream().filter(item -> item.getValue().equals(value))
+                .forEach(item -> item.selectedProperty().set(true));
+    }
+    void unSelectValue(Object value) {
+        checkListView.getItems().stream().filter(item -> item.getValue() == value)
+                .forEach(item -> item.selectedProperty().set(false));
+    }
+
+    FilterPanel(ColumnFilter<T,R> columnFilter, ContextMenu contextMenu) {
+        columnFilter.setFilterPanel(this);
+        this.columnFilter = columnFilter;
+        getStyleClass().add("filter-panel");
+
+        //initialize search box
+        setPadding(new Insets(3));
+
+        searchBox.setPromptText(promptText);
+        getChildren().add(searchBox);
+
+        //initialize checklist view
+
+        filterList = new FilteredList<>(new SortedList<>(columnFilter.getFilterValues()), t -> true);
+        checkListView = new ListView<>();
+        checkListView.setItems(new SortedList<>(filterList, FilterValue::compareTo));
+
+        getChildren().add(checkListView);
+
+        //initialize apply button
+        HBox buttonBox = new HBox();
+
+        Button applyBttn = new Button("APPLY");
+        HBox.setHgrow(applyBttn, Priority.ALWAYS);
+
+        applyBttn.setOnAction(e -> {
+                    if (searchMode) {
+                        filterList.forEach(v -> v.selectedProperty().setValue(true));
+
+                        columnFilter.getFilterValues().stream()
+                                .filter(v -> !filterList.stream().filter(fl -> fl.equals(v)).findAny().isPresent())
+                                .forEach(v -> v.selectedProperty().setValue(false));
+
+                        resetSearchFilter();
+                    }
+                    if (columnFilter.getTableFilter().isDirty()) {
+                        columnFilter.applyFilter();
+                        columnFilter.getTableFilter().getColumnFilters().stream().map(ColumnFilter::getFilterPanel)
+                                .forEach(fp -> {
+                                    if (!fp.columnFilter.hasUnselections()) {
+                                        fp.columnFilter.getTableColumn().setGraphic(null);
+                                    } else {
+                                        fp.columnFilter.getTableColumn().setGraphic(filterImageView.get());
+                                        if (!bumpedWidth) {
+                                            fp.columnFilter.getTableColumn().setPrefWidth(columnFilter.getTableColumn().getWidth() + 20);
+                                            bumpedWidth = true;
+                                        }
+                                    }
+                                });
+                    }
+                contextMenu.hide();
+                });
+
+        buttonBox.getChildren().add(applyBttn);
+
+        //initialize unselect all button
+        Button unselectAllButton = new Button("NONE");
+        HBox.setHgrow(unselectAllButton, Priority.ALWAYS);
+
+        unselectAllButton.setOnAction(e -> columnFilter.getFilterValues().forEach(v -> v.selectedProperty().set(false)));
+        buttonBox.getChildren().add(unselectAllButton);
+
+        //initialize reset buttons
+        Button selectAllButton = new Button("ALL");
+        HBox.setHgrow(selectAllButton, Priority.ALWAYS);
+
+        selectAllButton.setOnAction(e -> {
+            columnFilter.getFilterValues().forEach(v -> v.selectedProperty().set(true));
+        });
+
+        buttonBox.getChildren().add(selectAllButton);
+
+        Button clearAllButton = new Button("RESET ALL");
+        HBox.setHgrow(clearAllButton, Priority.ALWAYS);
+
+        clearAllButton.setOnAction(e -> {
+            columnFilter.resetAllFilters();
+            columnFilter.getTableFilter().getColumnFilters().stream().forEach(cf -> cf.getTableColumn().setGraphic(null));
+            contextMenu.hide();
+        });
+        buttonBox.getChildren().add(clearAllButton);
+
+        buttonBox.setAlignment(Pos.BASELINE_CENTER);
+
+
+        getChildren().add(buttonBox);
+    }
+
+    public void resetSearchFilter() {
+        this.filterList.setPredicate(t -> true);
+        searchBox.clear();
+    }
+    public static <T,R> CustomMenuItem getInMenuItem(ColumnFilter<T,R> columnFilter, ContextMenu contextMenu) {
+
+        FilterPanel<T,R> filterPanel = new FilterPanel<>(columnFilter, contextMenu);
+
+        CustomMenuItem menuItem = new CustomMenuItem();
+
+        filterPanel.initializeListeners();
+
+        menuItem.contentProperty().set(filterPanel);
+
+        columnFilter.getTableFilter().getTableView().skinProperty().addListener(new WeakChangeListener<>(filterPanel.skinListener));
+
+        menuItem.setHideOnClick(false);
+        return menuItem;
+    }
+    private void initializeListeners() {
+        searchBox.textProperty().addListener(l -> {
+            searchMode = !searchBox.getText().isEmpty();
+            filterList.setPredicate(val -> searchBox.getText().isEmpty() ||
+                    columnFilter.getSearchStrategy().test(searchBox.getText(), Optional.ofNullable(val.getValue()).map(Object::toString).orElse("")));
+        });
+    }
+
+    /* Methods below helps will anchor the context menu under the column */
+    private static void checkChangeContextMenu(TableViewSkin<?> skin, TableColumn<?, ?> column, FilterPanel filterPanel) {
+        NestedTableColumnHeader header = skin.getTableHeaderRow().getRootHeader();
+        InvalidationListener listener = filterPanel.getOrCreateChangeListener(header, column);
+        header.getColumnHeaders().addListener(new WeakInvalidationListener(listener));
+        changeContextMenu(header, column);
+    }
+
+    private InvalidationListener getOrCreateChangeListener(NestedTableColumnHeader header, TableColumn<?, ?> column) {
+        InvalidationListener listener = (Observable obs) -> changeContextMenu(header, column);
+
+        // Keep a reference locally because this listener will be used with a WeakInvalidationListener
+        columnHeadersChangeListeners.add(listener);
+
+        return listener;
+    }
+
+    private static void changeContextMenu(NestedTableColumnHeader header, TableColumn<?, ?> column) {
+        TableColumnHeader headerSkin = scan(column, header);
+        if (headerSkin != null) {
+            headerSkin.setOnContextMenuRequested(ev -> {
+                ContextMenu cMenu = column.getContextMenu();
+                if (cMenu != null) {
+                    cMenu.show(headerSkin, Side.BOTTOM, 5, 5);
+                }
+                ev.consume();
+            });
+        }
+    }
+
+    private static TableColumnHeader scan(TableColumn<?, ?> search,
+                                          TableColumnHeader header) {
+        // firstly test that the parent isn't what we are looking for
+        if (search.equals(header.getTableColumn())) {
+            return header;
+        }
+
+        if (header instanceof NestedTableColumnHeader) {
+            NestedTableColumnHeader parent = (NestedTableColumnHeader) header;
+            for (int i = 0; i < parent.getColumnHeaders().size(); i++) {
+                TableColumnHeader result = scan(search, parent
+                        .getColumnHeaders().get(i));
+                if (result != null) {
+                    return result;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public ColumnFilter<T,R> getColumnFilter() {
+        return columnFilter;
+    }
+}
diff --git a/src/impl/org/controlsfx/table/FilterValue.java b/src/impl/org/controlsfx/table/FilterValue.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc00c0591320f62aaa92dc451e7a285dd59d890a
--- /dev/null
+++ b/src/impl/org/controlsfx/table/FilterValue.java
@@ -0,0 +1,68 @@
+package impl.org.controlsfx.table;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.WeakInvalidationListener;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+import javafx.scene.layout.HBox;
+import javafx.scene.paint.Color;
+
+import java.util.Optional;
+
+final class FilterValue<T,R> extends HBox implements Comparable<FilterValue<T,R>> {
+
+    private final R value;
+    private final BooleanProperty isSelected = new SimpleBooleanProperty(true);
+    private final BooleanProperty inScope = new SimpleBooleanProperty(true);
+    private final ColumnFilter<T,R> columnFilter;
+    private final InvalidationListener scopeListener;
+
+
+    FilterValue(R value, ColumnFilter<T,R> columnFilter) {
+        this.value = value;
+        this.columnFilter = columnFilter;
+
+        final CheckBox checkBox = new CheckBox();
+        final Label label = new Label();
+        label.setText(Optional.ofNullable(value).map(Object::toString).orElse(null));
+        scopeListener = (Observable v) -> label.textFillProperty().set(getInScopeProperty().get() ? Color.BLACK : Color.LIGHTGRAY);
+        inScope.addListener(new WeakInvalidationListener(scopeListener));
+        checkBox.selectedProperty().bindBidirectional(selectedProperty());
+        getChildren().addAll(checkBox,label);
+    }
+
+    public R getValue() {
+        return value;
+    }
+
+    public BooleanProperty selectedProperty() {
+        return isSelected;
+    }
+    public BooleanProperty getInScopeProperty() {
+        return inScope;
+    }
+
+    public void refreshScope() {
+        inScope.setValue(columnFilter.wasLastFiltered() || columnFilter.valueIsVisible(value));
+    }
+
+    @Override
+    public String toString() {
+        return Optional.ofNullable(value).map(Object::toString).orElse("");
+    }
+
+
+    @Override
+    public int compareTo(FilterValue<T,R> other) {
+        if (value != null && other.value != null) {
+            if (value instanceof Comparable<?> && other.value instanceof Comparable<?>) {
+                return ((Comparable<Object>) value).compareTo(((Comparable<Object>) other.value));
+            }
+        }
+        return Optional.ofNullable(value).map(Object::toString).orElse("")
+                .compareTo(Optional.ofNullable(other).map(Object::toString).orElse(""));
+    }
+}
diff --git a/src/impl/org/controlsfx/table/filter.png b/src/impl/org/controlsfx/table/filter.png
new file mode 100644
index 0000000000000000000000000000000000000000..1098d3ac27a2c86136b60e2fb5e1b5e49bac6dfe
Binary files /dev/null and b/src/impl/org/controlsfx/table/filter.png differ
diff --git a/src/impl/org/controlsfx/table/no_filter.png b/src/impl/org/controlsfx/table/no_filter.png
new file mode 100644
index 0000000000000000000000000000000000000000..8861914d3125d46120d870d15c94385224f37fae
Binary files /dev/null and b/src/impl/org/controlsfx/table/no_filter.png differ
diff --git a/src/impl/org/controlsfx/table/tablefilter.css b/src/impl/org/controlsfx/table/tablefilter.css
new file mode 100644
index 0000000000000000000000000000000000000000..96e4c327ef8e30bab2a51ade1b1454ae981c9950
--- /dev/null
+++ b/src/impl/org/controlsfx/table/tablefilter.css
@@ -0,0 +1,7 @@
+.column-filter .custom-menu-item:focused {
+    -fx-background-color: transparent;
+}
+
+.filter-panel {
+    -fx-spacing: 10px
+}
\ No newline at end of file
diff --git a/src/impl/org/controlsfx/tools/MathTools.java b/src/impl/org/controlsfx/tools/MathTools.java
new file mode 100644
index 0000000000000000000000000000000000000000..6284bf63357e6980056497c2d986ed737d31fe7a
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/MathTools.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools;
+
+import java.util.Objects;
+
+/**
+ * Contains methods {@link Math} might also contain but doesn't.
+ */
+public class MathTools {
+
+    /**
+     * Checks whether the specified value lies in the closed interval defined by the specified bounds.
+     * 
+     * @param lowerBound
+     *            the interval's lower bound; included in the interval
+     * @param value
+     *            the value which will be checked
+     * @param upperBound
+     *            the interval's upper bound; included in the interval
+     * @return {@code true} if {@code lowerBound} <= {@code value} <= {@code upperBound} <br>
+     *         {@code false} otherwise
+     */
+    public static boolean isInInterval(double lowerBound, double value, double upperBound) {
+        return lowerBound <= value && value <= upperBound;
+    }
+
+    /**
+     * Checks whether the specified value lies in the closed interval defined by the specified bounds. If it does, it is
+     * returned; otherwise the bound closer to the value will be returned.
+     * 
+     * @param lowerBound
+     *            the interval's lower bound; included in the interval
+     * @param value
+     *            the value which will be checked
+     * @param upperBound
+     *            the interval's upper bound; included in the interval
+     * @return {@code value} if {@code lowerBound} <= {@code value} <= {@code upperBound} <br>
+     *         {@code lowerBound} if {@code value} < {@code lowerBound} <br>
+     *         {@code upperBound} if {@code upperBound} < {@code value}
+     */
+    public static double inInterval(double lowerBound, double value, double upperBound) {
+        if (value < lowerBound)
+            return lowerBound;
+        if (upperBound < value)
+            return upperBound;
+        return value;
+    }
+
+    /**
+     * Returns the smallest value in the specified array according to {@link Math#min(double, double)}.
+     * 
+     * @param values
+     *            a non-null, non-empty array of double values
+     * @return a value from the array which is smaller then or equal to any other value from the array
+     * @throws NullPointerException
+     *             if the values array is {@code null}
+     * @throws IllegalArgumentException
+     *             if the values array is empty (i.e. has {@code length} 0)
+     */
+    public static double min(double... values) {
+        Objects.requireNonNull(values, "The specified value array must not be null."); //$NON-NLS-1$
+        if (values.length == 0)
+            throw new IllegalArgumentException("The specified value array must contain at least one element."); //$NON-NLS-1$
+
+        double min = Double.MAX_VALUE;
+        for (double value : values)
+            min = Math.min(value, min);
+        return min;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/PrefixSelectionCustomizer.java b/src/impl/org/controlsfx/tools/PrefixSelectionCustomizer.java
new file mode 100644
index 0000000000000000000000000000000000000000..c03367cb169449536f2541edf25f10e0214ff51f
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/PrefixSelectionCustomizer.java
@@ -0,0 +1,221 @@
+/**
+ * Copyright (c) 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.controlsfx.control.PrefixSelectionChoiceBox;
+import org.controlsfx.control.PrefixSelectionComboBox;
+
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+import javafx.scene.control.ChoiceBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Control;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.util.StringConverter;
+
+/**
+ * <p>This utility class can be used to customize a {@link ChoiceBox} or
+ * {@link ComboBox} and enable the "prefix selection" feature. This will enable
+ * the user to type letters or digits on the keyboard while the {@link ChoiceBox}
+ * or {@link ComboBox} has the focus. The {@link ChoiceBox} or {@link ComboBox} 
+ * will attempt to select the first item it can find with a matching prefix ignoring 
+ * case.
+ * 
+ * <p>This feature is available natively on the Windows combo box control, so many
+ * users have asked for it. There is a feature request to include this feature
+ * into JavaFX (<a href="https://javafx-jira.kenai.com/browse/RT-18064">Issue RT-18064</a>). 
+ * The class is published as part of ContorlsFX to allow testing and feedback.
+ * 
+ * <h3>Example</h3>
+ *  
+ * <p>Let's look at an example to clarify this. The combo box offers the items 
+ * ["Aaaaa", "Abbbb", "Abccc", "Abcdd", "Abcde"]. The user now types "abc" in 
+ * quick succession (and then stops typing). The combo box will select a new entry 
+ * on every key pressed. The first entry it will select is "Aaaaa" since it is the 
+ * first entry that starts with an "a" (case ignored). It will then select "Abbbb", 
+ * since this is the first entry that started with "ab" and will finally settle for 
+ * "Abccc".
+ * 
+ * <ul><table>
+ *   <tr><th>Keys typed</th><th>Element selected</th></tr>
+ *   <tr><td>a</td><td>Aaaaa<td></tr>
+ *   <tr><td>aaa</td><td>Aaaaa<td></tr>
+ *   <tr><td>ab</td><td>Abbbb<td></tr>
+ *   <tr><td>abc</td><td>Abccc<td></tr>
+ *   <tr><td>xyz</td><td>-<td></tr>
+ * </table></ul>
+ * 
+ * <h3>Usage</h3>
+ * 
+ * <p>A common use case is to customize a {@link ChoiceBox} or {@link ComboBox}
+ * that has been loaded as part of an FXML. In this case you can use the utility
+ * methods {@link #customize(ChoiceBox)} or {@link #customize(ComboBox)}. This
+ * will install a {@link EventHandler} that monitors the {@link KeyEvent}
+ * events.
+ * 
+ * <p>If you are coding, you can also use the preconfigured classes
+ * {@link PrefixSelectionChoiceBox} and {@link PrefixSelectionComboBox} as a
+ * substitute for {@link ChoiceBox} and {@link ComboBox}.
+ * 
+ * @see PrefixSelectionChoiceBox
+ * @see PrefixSelectionComboBox
+ */
+public class PrefixSelectionCustomizer {
+    private static final String SELECTION_PREFIX_STRING = "selectionPrefixString";
+    private static final Object SELECTION_PREFIX_TASK = "selectionPrefixTask";
+
+    private static EventHandler<KeyEvent> handler = new EventHandler<KeyEvent>() {
+        private ScheduledExecutorService executorService = null;
+
+        @Override
+        public void handle(KeyEvent event) {
+            keyPressed(event);
+        }
+
+        private <T> void keyPressed(KeyEvent event) {
+            KeyCode code = event.getCode();
+            if (code.isLetterKey() || code.isDigitKey() || code == KeyCode.SPACE) {
+                String letter = code.impl_getChar();
+                if (event.getSource() instanceof ComboBox) {
+                    ComboBox<T> comboBox = (ComboBox<T>) event.getSource();
+                    T item = getEntryWithKey(letter, comboBox.getConverter(), comboBox.getItems(), comboBox);
+                    if (item != null) {
+                        comboBox.setValue(item);
+                    }
+                } else if (event.getSource() instanceof ChoiceBox) {
+                    ChoiceBox<T> choiceBox = (ChoiceBox<T>) event.getSource();
+                    T item = getEntryWithKey(letter, choiceBox.getConverter(), choiceBox.getItems(), choiceBox);
+                    if (item != null) {
+                        choiceBox.setValue(item);
+                    }
+                }
+            }
+        }
+
+        private <T> T getEntryWithKey(String letter, StringConverter<T> converter, ObservableList<T> items, Control control) {
+            T result = null;
+
+            // The converter is null by default for the ChoiceBox. The ComboBox has a default converter
+            if (converter == null) {
+                converter = new StringConverter<T>() {
+                    @Override
+                    public String toString(T t) {
+                        return t == null ? null : t.toString();
+                    }
+
+                    @Override
+                    public T fromString(String string) {
+                        return null;
+                    }
+                };
+            }
+
+            String selectionPrefixString = (String) control.getProperties().get(SELECTION_PREFIX_STRING);
+            if (selectionPrefixString == null) {
+                selectionPrefixString = letter.toUpperCase();
+            } else {
+                selectionPrefixString += letter.toUpperCase();
+            }
+            control.getProperties().put(SELECTION_PREFIX_STRING, selectionPrefixString);
+
+            for (T item : items) {
+                String string = converter.toString(item);
+                if (string != null && string.toUpperCase().startsWith(selectionPrefixString)) {
+                    result = item;
+                    break;
+                }
+            }
+
+            ScheduledFuture<?> task = (ScheduledFuture<?>) control.getProperties().get(SELECTION_PREFIX_TASK);
+            if (task != null) {
+                task.cancel(false);
+            }
+            task = getExecutorService().schedule(
+                    () -> control.getProperties().put(SELECTION_PREFIX_STRING, ""), 500, TimeUnit.MILLISECONDS); 
+            control.getProperties().put(SELECTION_PREFIX_TASK, task);
+
+            return result;
+        }
+
+        private ScheduledExecutorService getExecutorService() {
+            if (executorService == null) {
+                executorService = Executors.newScheduledThreadPool(1,
+                        runnabble -> {
+                            Thread result = new Thread(runnabble);
+                            result.setDaemon(true);
+                            return result;
+                        });
+            }
+            return executorService;
+        }
+
+    };
+
+    /**
+     * This will install an {@link EventHandler} that monitors the
+     * {@link KeyEvent} events to enable the "prefix selection" feature.
+     * The {@link EventHandler} will only be installed if the {@link ComboBox}
+     * is <b>not</b> editable.
+     * 
+     * @param comboBox
+     *            The {@link ComboBox} that should be customized
+     * 
+     * @see PrefixSelectionCustomizer
+     */
+    public static void customize(ComboBox<?> comboBox) {
+        if (!comboBox.isEditable()) {
+            comboBox.addEventHandler(KeyEvent.KEY_PRESSED, handler);
+        }
+        comboBox.editableProperty().addListener((o, oV, nV) -> {
+            if (!nV) {
+                comboBox.addEventHandler(KeyEvent.KEY_PRESSED, handler);
+            } else {
+                comboBox.removeEventHandler(KeyEvent.KEY_PRESSED, handler);
+            }
+        });
+    }
+
+    /**
+     * This will install an {@link EventHandler} that monitors the
+     * {@link KeyEvent} events to enable the "prefix selection" feature.
+     * 
+     * @param choiceBox
+     *            The {@link ChoiceBox} that should be customized
+     * 
+     * @see PrefixSelectionCustomizer
+     */
+    public static void customize(ChoiceBox<?> choiceBox) {
+        choiceBox.addEventHandler(KeyEvent.KEY_PRESSED, handler);
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/CoordinatePosition.java b/src/impl/org/controlsfx/tools/rectangle/CoordinatePosition.java
new file mode 100644
index 0000000000000000000000000000000000000000..e0157013be9a9287ecb177ef1aa0e795c4a12920
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/CoordinatePosition.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle;
+
+/**
+ * Enumerates all possible positions coordinates can have relative to a rectangle.
+ */
+public enum CoordinatePosition {
+
+    /**
+     * The coordinates are inside the rectangle.
+     */
+    IN_RECTANGLE,
+
+    /**
+     * The coordinates are outside of the rectangle.
+     */
+    OUT_OF_RECTANGLE,
+
+    /**
+     * The coordinates are close to the northern edge of the rectangle.
+     */
+    NORTH_EDGE,
+
+    /**
+     * The coordinates are close to the northern and the eastern edge of the rectangle.
+     */
+    NORTHEAST_EDGE,
+
+    /**
+     * The coordinates are close to the eastern edge of the rectangle.
+     */
+    EAST_EDGE,
+
+    /**
+     * The coordinates are close to the southern and eastern edge of the rectangle.
+     */
+    SOUTHEAST_EDGE,
+
+    /**
+     * The coordinates are close to the southern edge of the rectangle.
+     */
+    SOUTH_EDGE,
+
+    /**
+     * The coordinates are close to the southern and western edge of the rectangle.
+     */
+    SOUTHWEST_EDGE,
+
+    /**
+     * The coordinates are close to the western edge of the rectangle.
+     */
+    WEST_EDGE,
+
+    /**
+     * The coordinates are close to the northern and the western edge of the rectangle.
+     */
+    NORTHWEST_EDGE,
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/CoordinatePositions.java b/src/impl/org/controlsfx/tools/rectangle/CoordinatePositions.java
new file mode 100644
index 0000000000000000000000000000000000000000..13ec0092185b11e7d5a398cc9cb6b2eaaa69f998
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/CoordinatePositions.java
@@ -0,0 +1,222 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle;
+
+import java.util.EnumSet;
+
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * Computes coordinate positions relative to a rectangle.
+ */
+public class CoordinatePositions {
+
+    /**
+     * Returns all positions the specified point has regarding the specified rectangle and its edges (using the
+     * specified tolerance).
+     * 
+     * @param rectangle
+     *            the rectangle relative to which the point will be checked
+     * @param point
+     *            the checked point
+     * @param edgeTolerance
+     *            the tolerance in pixels used to determine whether the coordinates are on some edge
+     * @return a set of those positions the coordinates have regarding the specified rectangle
+     */
+    public static EnumSet<CoordinatePosition> onRectangleAndEdges(
+            Rectangle2D rectangle, Point2D point, double edgeTolerance) {
+
+        EnumSet<CoordinatePosition> positions = EnumSet.noneOf(CoordinatePosition.class);
+        positions.add(inRectangle(rectangle, point));
+        positions.add(onEdges(rectangle, point, edgeTolerance));
+        return positions;
+    }
+
+    /*
+     * RECTANGLE
+     */
+
+    /**
+     * Returns the position the specified coordinates have regarding the specified rectangle. Edges are not checked.
+     * 
+     * @param rectangle
+     *            the rectangle relative to which the point will be checked
+     * @param point
+     *            the checked point
+     * @return depending on the point either {@link CoordinatePosition#IN_RECTANGLE IN_RECTANGLE} or
+     *         {@link CoordinatePosition#OUT_OF_RECTANGLE OUT_OF_RECTANGLE}
+     */
+    public static CoordinatePosition inRectangle(Rectangle2D rectangle, Point2D point) {
+        if (rectangle.contains(point)) {
+            return CoordinatePosition.IN_RECTANGLE;
+        } else {
+            return CoordinatePosition.OUT_OF_RECTANGLE;
+        }
+    }
+
+    /*
+     * EDGES
+     */
+
+    /**
+     * Returns the position the specified coordinates have regarding the specified rectangle's edges using the specified
+     * tolerance.
+     * 
+     * @param rectangle
+     *            the rectangle relative to which the point will be checked
+     * @param point
+     *            the checked point
+     * @param edgeTolerance
+     *            the tolerance in pixels used to determine whether the coordinates are on some edge
+     * @return the edge position the coordinates have regarding the specified rectangle; the value will be null if the
+     *         point is not near any edge
+     */
+    public static CoordinatePosition onEdges(Rectangle2D rectangle, Point2D point,
+            double edgeTolerance) {
+
+        CoordinatePosition vertical = closeToVertical(rectangle, point, edgeTolerance);
+        CoordinatePosition horizontal = closeToHorizontal(rectangle, point, edgeTolerance);
+
+        return extractSingleCardinalDirection(vertical, horizontal);
+    }
+
+    /**
+     * Returns the vertical bound the specified coordinates are closest to, if the distance is smaller than the edge
+     * tolerance. Otherwise, null is returned.
+     * 
+     * @param rectangle
+     *            the rectangle relative to which the point will be checked
+     * @param point
+     *            the checked point
+     * @param edgeTolerance
+     *            the tolerance in pixels used to determine whether the coordinates are on some edge
+     * @return EAST_EDGE, WEST_EDGE or null
+     */
+    private static CoordinatePosition closeToVertical(Rectangle2D rectangle, Point2D point, double edgeTolerance) {
+
+        double xDistanceToLeft = Math.abs(point.getX() - rectangle.getMinX());
+        double xDistanceToRight = Math.abs(point.getX() - rectangle.getMaxX());
+        boolean xCloseToLeft = xDistanceToLeft < edgeTolerance && xDistanceToLeft < xDistanceToRight;
+        boolean xCloseToRight = xDistanceToRight < edgeTolerance && xDistanceToRight < xDistanceToLeft;
+
+        if (!xCloseToLeft && !xCloseToRight) {
+            return null;
+        }
+
+        boolean yCloseToVertical = rectangle.getMinY() - edgeTolerance < point.getY()
+                && point.getY() < rectangle.getMaxY() + edgeTolerance;
+        if (yCloseToVertical) {
+            if (xCloseToLeft) {
+                return CoordinatePosition.WEST_EDGE;
+            }
+            if (xCloseToRight) {
+                return CoordinatePosition.EAST_EDGE;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the horizontal bound the specified coordinates are closest to, if the distance is smaller than the edge
+     * tolerance. Otherwise, null is returned.
+     * 
+     * @param rectangle
+     *            the rectangle relative to which the point will be checked
+     * @param point
+     *            the checked point
+     * @param edgeTolerance
+     *            the tolerance in pixels used to determine whether the coordinates are on some edge
+     * @return NORTH_EDGE, SOUTH_EDGE or null
+     */
+    private static CoordinatePosition closeToHorizontal(Rectangle2D rectangle, Point2D point, double edgeTolerance) {
+
+        double yDistanceToUpper = Math.abs(point.getY() - rectangle.getMinY());
+        double yDistanceToLower = Math.abs(point.getY() - rectangle.getMaxY());
+        boolean yCloseToUpper = yDistanceToUpper < edgeTolerance && yDistanceToUpper < yDistanceToLower;
+        boolean yCloseToLower = yDistanceToLower < edgeTolerance && yDistanceToLower < yDistanceToUpper;
+
+        if (!yCloseToUpper && !yCloseToLower) {
+            return null;
+        }
+
+        boolean xCloseToHorizontal = rectangle.getMinX() - edgeTolerance < point.getX()
+                && point.getX() < rectangle.getMaxX() + edgeTolerance;
+        if (xCloseToHorizontal) {
+            if (yCloseToUpper) {
+                return CoordinatePosition.NORTH_EDGE;
+            }
+            if (yCloseToLower) {
+                return CoordinatePosition.SOUTH_EDGE;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Extracts a single cardinal direction from the two specified positions. The conditions stated below are not
+     * checked!
+     * 
+     * @param vertical
+     *            a vertical edge (EAST or WEST) or null
+     * @param horizontal
+     *            a horizontal edge (NORTH OR SOUTH) or null
+     * @return the single coordinate position which matches the specified positions <br>
+     *         (e.g. NORTH for (null, NORTH) and SOUTHWEST for (WEST, SOUTH))
+     */
+    private static CoordinatePosition extractSingleCardinalDirection(CoordinatePosition vertical,
+            CoordinatePosition horizontal) {
+        if (vertical == null) {
+            return horizontal;
+        }
+
+        if (horizontal == null) {
+            return vertical;
+        }
+
+        // north
+        if (horizontal == CoordinatePosition.NORTH_EDGE && vertical == CoordinatePosition.EAST_EDGE) {
+            return CoordinatePosition.NORTHEAST_EDGE;
+        }
+        if (horizontal == CoordinatePosition.NORTH_EDGE && vertical == CoordinatePosition.WEST_EDGE) {
+            return CoordinatePosition.NORTHWEST_EDGE;
+        }
+
+        // south
+        if (horizontal == CoordinatePosition.SOUTH_EDGE && vertical == CoordinatePosition.EAST_EDGE) {
+            return CoordinatePosition.SOUTHEAST_EDGE;
+        }
+        if (horizontal == CoordinatePosition.SOUTH_EDGE && vertical == CoordinatePosition.WEST_EDGE) {
+            return CoordinatePosition.SOUTHWEST_EDGE;
+        }
+
+        throw new IllegalArgumentException();
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/Edge2D.java b/src/impl/org/controlsfx/tools/rectangle/Edge2D.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9f17e6fa7e67a0b91ed1cfa5ecf2f99d158865f
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/Edge2D.java
@@ -0,0 +1,249 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle;
+
+import java.util.Objects;
+
+import javafx.geometry.Orientation;
+import javafx.geometry.Point2D;
+
+/**
+ * The edge of a rectangle, i.e. a vertical or horizontal line segment.
+ */
+public class Edge2D {
+
+    /*
+     * ATTRIBUTES
+     */
+
+    /**
+     * The edge's center point.
+     */
+    private final Point2D centerPoint;
+
+    /**
+     * The edge's orientation.
+     */
+    private final Orientation orientation;
+
+    /**
+     * The edge's length.
+     */
+    private final double length;
+
+    /*
+     * ATTRIBUTES
+     */
+
+    /**
+     * Creates a new edge which is specified by its center point, orientation and length.
+     * 
+     * @param centerPoint
+     *            the edge's center point
+     * @param orientation
+     *            the edge's orientation
+     * @param length
+     *            the edge's length; must be non-negative.
+     */
+    public Edge2D(Point2D centerPoint, Orientation orientation, double length) {
+        Objects.requireNonNull(centerPoint, "The specified center point must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(orientation, "The specified orientation must not be null."); //$NON-NLS-1$
+        if (length < 0)
+            throw new IllegalArgumentException(
+                    "The length must not be negative, i.e. zero or a positive value is alowed."); //$NON-NLS-1$
+
+        this.centerPoint = centerPoint;
+        this.orientation = orientation;
+        this.length = length;
+    }
+
+    /*
+     * CORNERS AND DISTANCES
+     */
+
+    /**
+     * Returns the edge's upper left end point. It has ({@link #getLength() length} / 2) distance from the center point
+     * and depending on the edge's orientation either the same X (for {@link Orientation#HORIZONTAL}) or Y (for
+     * {@link Orientation#VERTICAL}) coordinate.
+     * 
+     * @return the edge's upper left point
+     */
+    public Point2D getUpperLeft() {
+        if (isHorizontal()) {
+            // horizontal
+            double cornersX = centerPoint.getX() - (length / 2);
+            double edgesY = centerPoint.getY();
+            return new Point2D(cornersX, edgesY);
+        } else {
+            // vertical
+            double edgesX = centerPoint.getX();
+            double cornersY = centerPoint.getY() - (length / 2);
+            return new Point2D(edgesX, cornersY);
+        }
+    }
+
+    /**
+     * Returns the edge's lower right end point. It has ({@link #getLength() length} / 2) distance from the center point
+     * and depending on the edge's orientation either the same X (for {@link Orientation#HORIZONTAL}) or Y (for
+     * {@link Orientation#VERTICAL}) coordinate.
+     * 
+     * @return the edge's lower right point
+     */
+    public Point2D getLowerRight() {
+        if (isHorizontal()) {
+            // horizontal
+            double cornersX = centerPoint.getX() + (length / 2);
+            double edgesY = centerPoint.getY();
+            return new Point2D(cornersX, edgesY);
+        } else {
+            // vertical
+            double edgesX = centerPoint.getX();
+            double cornersY = centerPoint.getY() + (length / 2);
+            return new Point2D(edgesX, cornersY);
+        }
+    }
+
+    /**
+     * Returns the distance of the specified point to the edge in terms of the dimension orthogonal to the edge's
+     * orientation. The sign denotes whether on which side of the edge, the point lies.<br>
+     * So e.g. if the edge is horizontal, only the Y coordinate's difference between the specified point and the edge is
+     * considered. If the point lies to the right of the edge, the returned value is positive.
+     * 
+     * @param otherPoint
+     *            the point to where the distance is computed
+     * @return the distance
+     */
+    public double getOrthogonalDifference(Point2D otherPoint) {
+        Objects.requireNonNull(otherPoint, "The other point must nt be null."); //$NON-NLS-1$
+
+        if (isHorizontal())
+            // horizontal -> subtract y coordinates
+            return otherPoint.getY() - centerPoint.getY();
+        else
+            // vertical-> subtract x coordinates
+            return otherPoint.getX() - centerPoint.getX();
+    }
+
+    /*
+     * ATTRIBUTE ACCESS
+     */
+
+    /**
+     * @return the edge's center point
+     */
+    public Point2D getCenterPoint() {
+        return centerPoint;
+    }
+
+    /**
+     * Returns this edge's orientation. Note that the orientation can also be checked with {@link #isHorizontal()} and
+     * {@link #isVertical()}.
+     * 
+     * @return the edge's orientation
+     */
+    public Orientation getOrientation() {
+        return orientation;
+    }
+
+    /**
+     * Indicates whether this is a {@link Orientation#HORIZONTAL horizontal} edge.
+     * 
+     * @return true if {@link #getOrientation()} returns {@link Orientation#HORIZONTAL}
+     */
+    public boolean isHorizontal() {
+        return orientation == Orientation.HORIZONTAL;
+    }
+
+    /**
+     * Indicates whether this is a {@link Orientation#VERTICAL horizontal} edge.
+     * 
+     * @return true if {@link #getOrientation()} returns {@link Orientation#VERTICAL}
+     */
+    public boolean isVertical() {
+        return orientation == Orientation.VERTICAL;
+    }
+
+    /**
+     * @return the edge's length
+     */
+    public double getLength() {
+        return length;
+    }
+
+    /*
+     * EQUALS, HASHCODE & TOSTRING
+     */
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((centerPoint == null) ? 0 : centerPoint.hashCode());
+        long temp;
+        temp = Double.doubleToLongBits(length);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        result = prime * result + ((orientation == null) ? 0 : orientation.hashCode());
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        Edge2D other = (Edge2D) obj;
+        if (centerPoint == null) {
+            if (other.centerPoint != null)
+                return false;
+        } else if (!centerPoint.equals(other.centerPoint))
+            return false;
+        if (Double.doubleToLongBits(length) != Double.doubleToLongBits(other.length))
+            return false;
+        if (orientation != other.orientation)
+            return false;
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return "Edge2D [centerX = " + centerPoint.getX() + ", centerY = " + centerPoint.getY() //$NON-NLS-1$ //$NON-NLS-2$
+                + ", orientation = " + orientation + ", length = " + length + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/Rectangles2D.java b/src/impl/org/controlsfx/tools/rectangle/Rectangles2D.java
new file mode 100644
index 0000000000000000000000000000000000000000..80f5d9062b9634e7c57c8ea770d673fbc9226ba2
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/Rectangles2D.java
@@ -0,0 +1,796 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle;
+
+import impl.org.controlsfx.tools.MathTools;
+
+import java.util.Objects;
+
+import javafx.geometry.Bounds;
+import javafx.geometry.Orientation;
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * Usability methods for rectangles.
+ */
+public class Rectangles2D {
+
+    /*
+     * CHECKS
+     */
+
+    /**
+     * Indicates whether the specified rectangle contains the specified edge.
+     * 
+     * @param rectangle
+     *            the rectangle to check
+     * @param edge
+     *            the edge to check
+     * @return {@code true} if both end points of the edge are {@link Rectangle2D#contains(Point2D) contained} in the
+     *         rectangle
+     */
+    public static boolean contains(Rectangle2D rectangle, Edge2D edge) {
+        Objects.requireNonNull(rectangle, "The argument 'rectangle' must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(edge, "The argument 'edge' must not be null."); //$NON-NLS-1$
+
+        boolean edgeInBounds = rectangle.contains(edge.getUpperLeft()) && rectangle.contains(edge.getLowerRight());
+        return edgeInBounds;
+    }
+
+    /*
+     * POINT
+     */
+
+    /**
+     * Moves the specified point into the specified rectangle. If the point is already with the rectangle, it is
+     * returned. Otherwise the point in the rectangle which is closest to the specified one is returned.
+     * 
+     * @param rectangle
+     *            the {@link Rectangle2D} into which the point should be moved
+     * @param point
+     *            the {@link Point2D} which is checked
+     * @return either the specified {@code point} or the {@link Point2D} which is closest to it while still being
+     *         contained on the {@code rectangle}
+     */
+    public static Point2D inRectangle(Rectangle2D rectangle, Point2D point) {
+        Objects.requireNonNull(rectangle, "The argument 'rectangle' must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(point, "The argument 'point' must not be null."); //$NON-NLS-1$
+
+        if (rectangle.contains(point)) {
+            return point;
+        }
+
+        // force the x and y coordinate into the rectangle
+        double newX = MathTools.inInterval(rectangle.getMinX(), point.getX(), rectangle.getMaxX());
+        double newY = MathTools.inInterval(rectangle.getMinY(), point.getY(), rectangle.getMaxY());
+        return new Point2D(newX, newY);
+    }
+
+    /**
+     * Returns the center of the specified rectangle as a point.
+     * 
+     * @param rectangle
+     *            the {@link Rectangle2D} whose center point will be returned
+     * @return the {@link Point2D} whose x/y coordinates lie at {@code (min + max) / 2}.
+     */
+    public static Point2D getCenterPoint(Rectangle2D rectangle) {
+        Objects.requireNonNull(rectangle, "The argument 'rectangle' must not be null."); //$NON-NLS-1$
+
+        double centerX = (rectangle.getMinX() + rectangle.getMaxX()) / 2;
+        double centerY = (rectangle.getMinY() + rectangle.getMaxY()) / 2;
+        return new Point2D(centerX, centerY);
+    }
+
+    /*
+     * OTHER RECTANGLE
+     */
+
+    /**
+     * Returns the rectangle which represents the intersection of the two specified rectangles.
+     * 
+     * @param a
+     *            a {@link Rectangle2D}
+     * @param b
+     *            another {@link Rectangle2D}
+     * @return a {@link Rectangle2D} which is the intersection of {@code a} and {@code b}; possible
+     *         {@link Rectangle2D#EMPTY}.
+     */
+    public static Rectangle2D intersection(Rectangle2D a, Rectangle2D b) {
+        Objects.requireNonNull(a, "The argument 'a' must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(b, "The argument 'b' must not be null."); //$NON-NLS-1$
+
+        if (a.intersects(b)) {
+            double intersectionMinX = Math.max(a.getMinX(), b.getMinX());
+            double intersectionMaxX = Math.min(a.getMaxX(), b.getMaxX());
+            double intersectionWidth = intersectionMaxX - intersectionMinX;
+            double intersectionMinY = Math.max(a.getMinY(), b.getMinY());
+            double intersectionMaxY = Math.min(a.getMaxY(), b.getMaxY());
+            double intersectionHeight = intersectionMaxY - intersectionMinY;
+            return new Rectangle2D(intersectionMinX, intersectionMinY, intersectionWidth, intersectionHeight);
+        } else {
+            return Rectangle2D.EMPTY;
+        }
+    }
+
+    /*
+     * TWO CORNERS
+     */
+
+    /**
+     * Creates a new rectangle with the two specified corners. The two corners will be interpreted as being diagonal of
+     * each other.
+     * 
+     * @param oneCorner
+     *            one corner
+     * @param diagonalCorner
+     *            another corner, diagonal from the first
+     * @return the {@link Rectangle2D} which is defined by the two corners
+     */
+    public static Rectangle2D forDiagonalCorners(Point2D oneCorner, Point2D diagonalCorner) {
+        Objects.requireNonNull(oneCorner, "The specified corner must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(diagonalCorner, "The specified diagonal corner must not be null."); //$NON-NLS-1$
+
+        double minX = Math.min(oneCorner.getX(), diagonalCorner.getX());
+        double minY = Math.min(oneCorner.getY(), diagonalCorner.getY());
+        double width = Math.abs(oneCorner.getX() - diagonalCorner.getX());
+        double height = Math.abs(oneCorner.getY() - diagonalCorner.getY());
+
+        return new Rectangle2D(minX, minY, width, height);
+    }
+
+    /*
+     * CORNER AND SIZE
+     */
+
+    /**
+     * Creates a new rectangle with the specified {@code upperLeft} corner and the specified {@code width} and
+     * {@code height}.
+     * 
+     * @param upperLeft
+     *            one corner
+     * @param width
+     *            the new rectangle's width
+     * @param height
+     *            the new rectangle's height
+     * @return the {@link Rectangle2D} which is defined by the specified upper left corner and width and height
+     */
+    public static Rectangle2D forUpperLeftCornerAndSize(Point2D upperLeft, double width, double height) {
+        return new Rectangle2D(upperLeft.getX(), upperLeft.getY(), width, height);
+    }
+
+    /*
+     * CORNER AND RATIO
+     */
+
+    /**
+     * Creates a new rectangle with the two specified corners. The two corners will be interpreted as being diagonal of
+     * each other. The returned rectangle will have the specified {@code fixedCorner} as its corner. The other one will
+     * either be on the same x- or y-parallel as the {@code diagonalCorner} but will be such that the rectangle has the
+     * specified {@code ratio}.
+     * 
+     * @param fixedCorner
+     *            one corner
+     * @param diagonalCorner
+     *            another corner, diagonal from the first
+     * @param ratio
+     *            the ratio the returned rectangle must have; must be non-negative
+     * @return the {@link Rectangle2D} which is defined by the {@code fixedCorner}, the x- or y-parallel of the
+     *         {@code diagonalCorner} and the {@code ratio}
+     */
+    public static Rectangle2D forDiagonalCornersAndRatio(Point2D fixedCorner, Point2D diagonalCorner, double ratio) {
+        Objects.requireNonNull(fixedCorner, "The specified fixed corner must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(diagonalCorner, "The specified diagonal corner must not be null."); //$NON-NLS-1$
+        if (ratio < 0) {
+            throw new IllegalArgumentException("The specified ratio " + ratio + " must be larger than zero."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        // the coordinate differences - note that they can be negative
+        double xDifference = diagonalCorner.getX() - fixedCorner.getX();
+        double yDifference = diagonalCorner.getY() - fixedCorner.getY();
+
+        // the following calls will only change one of the two differences:
+        // the one whose value is too large compared to what it should be based on the other difference and the ratio;
+        // its value will instead be the other difference time or divided by the ratio
+        double xDifferenceByRatio = correctCoordinateDifferenceByRatio(xDifference, yDifference, ratio);
+        double yDifferenceByRatio = correctCoordinateDifferenceByRatio(yDifference, xDifference, 1 / ratio);
+
+        // these are the coordinates of the upper left corner of the future rectangle
+        double minX = getMinCoordinate(fixedCorner.getX(), xDifferenceByRatio);
+        double minY = getMinCoordinate(fixedCorner.getY(), yDifferenceByRatio);
+
+        double width = Math.abs(xDifferenceByRatio);
+        double height = Math.abs(yDifferenceByRatio);
+
+        return new Rectangle2D(minX, minY, width, height);
+    }
+
+    /**
+     * Returns the difference with the following properties:<br>
+     * - it has the same sign as the specified difference <br>
+     * - its absolute value is the minimum of the absolute values of ...<br>
+     * ... the specified difference and <br>
+     * ... the product of the specified ratio and the other specified difference <br>
+     * 
+     * @param difference
+     *            the difference to check
+     * @param otherDifference
+     *            the other difference
+     * @param ratioAsMultiplier
+     *            the ratio as a multiplier for the other difference
+     * @return the corrected difference
+     */
+    private static double correctCoordinateDifferenceByRatio(double difference, double otherDifference,
+            double ratioAsMultiplier) {
+        double differenceByRatio = otherDifference * ratioAsMultiplier;
+        double correctedDistance = Math.min(Math.abs(difference), Math.abs(differenceByRatio));
+
+        return correctedDistance * Math.signum(difference);
+    }
+
+    /**
+     * Returns the minimum coordinate such that a rectangle starting from that coordinate will contain the fixed
+     * coordinate as a corner.
+     * 
+     * @param fixedCoordinate
+     *            the coordinate which must be a corner
+     * @param difference
+     *            the difference in the computed coordinate
+     * @return fixedCoordinate + difference; if difference < 0 <br>
+     *         fixedCoordinate; else
+     */
+    private static double getMinCoordinate(double fixedCoordinate, double difference) {
+        if (difference < 0) {
+            return fixedCoordinate + difference;
+        }
+
+        return fixedCoordinate;
+    }
+
+    /*
+     * CENTER AND SIZE
+     */
+
+    /**
+     * Creates a new rectangle with the specified center and the specified width and height.
+     * 
+     * @param centerPoint
+     *            the center point o the new rectangle
+     * @param width
+     *            the width of the new rectangle
+     * @param height
+     *            the height of the new rectangle
+     * @return a rectangle with the specified center and size
+     */
+    public static Rectangle2D forCenterAndSize(Point2D centerPoint, double width, double height) {
+        Objects.requireNonNull(centerPoint, "The specified center point must not be null."); //$NON-NLS-1$
+
+        double absoluteWidth = Math.abs(width);
+        double absoluteHeight = Math.abs(height);
+        double minX = centerPoint.getX() - absoluteWidth / 2;
+        double minY = centerPoint.getY() - absoluteHeight / 2;
+
+        return new Rectangle2D(minX, minY, width, height);
+    }
+
+    /*
+     * ORIGINAL, AREA AND RATIO
+     */
+
+    /**
+     * Creates a new rectangle with the same center point and area as the specified {@code original} rectangle with the
+     * specified {@code ratio}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratio
+     *            the new ratio
+     * @return a new {@link Rectangle2D} with the same center point as the {@code original} and the specified
+     *         {@code ratio}; it has the same area as the {@code original}
+     * @throws NullPointerException
+     *             if the {@code original} rectangle is null
+     */
+    public static Rectangle2D fixRatio(Rectangle2D original, double ratio) {
+        Objects.requireNonNull(original, "The specified original rectangle must not be null."); //$NON-NLS-1$
+        if (ratio < 0) {
+            throw new IllegalArgumentException("The specified ratio " + ratio + " must be larger than zero."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return createWithFixedRatioWithinBounds(original, ratio, null);
+    }
+
+    /**
+     * Creates a new rectangle with the same center point and area (if possible) as the specified {@code original}
+     * rectangle with the specified {@code ratio} and respecting the specified {@code bounds}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratio
+     *            the new ratio
+     * @param bounds
+     *            the bounds within which the new rectangle will be located
+     * @return a new {@link Rectangle2D} with the same center point as the {@code original} and the specified
+     *         {@code ratio}; it has the same area as the {@code original} unless this would violate the bounds; in this
+     *         case it is as large as possible while still staying within the bounds
+     * @throws NullPointerException
+     *             if the {@code original} or {@code bounds} rectangle is null
+     * @throws IllegalArgumentException
+     *             if the {@code original} rectangle's center point is out of the bounds
+     */
+    public static Rectangle2D fixRatioWithinBounds(Rectangle2D original, double ratio, Rectangle2D bounds) {
+        Objects.requireNonNull(original, "The specified original rectangle must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(bounds, "The specified bounds for the new rectangle must not be null."); //$NON-NLS-1$
+        if (ratio < 0) {
+            throw new IllegalArgumentException("The specified ratio " + ratio + " must be larger than zero."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return createWithFixedRatioWithinBounds(original, ratio, bounds);
+    }
+
+    /**
+     * Creates a new rectangle with the same center point and area as the specified {@code original} rectangle with the
+     * specified {@code ratio} and respecting the specified {@code bounds} (if not-{@code null}).
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratio
+     *            the new ratio
+     * @param bounds
+     *            the bounds within which the new rectangle will be located; might be {@code null}
+     * @return a new {@link Rectangle2D} with the same center point as the {@code original} and the specified
+     *         {@code ratio}; it has the same area as the {@code original} unless this would violate the bounds; in this
+     *         case it is as large as possible while still staying within the bounds
+     * @throws IllegalArgumentException
+     *             if the {@code original} rectangle's center point is out of the {@code bounds}
+     */
+    private static Rectangle2D createWithFixedRatioWithinBounds(Rectangle2D original, double ratio, Rectangle2D bounds) {
+        Point2D centerPoint = getCenterPoint(original);
+
+        boolean centerPointInBounds = bounds == null || bounds.contains(centerPoint);
+        if (!centerPointInBounds) {
+            throw new IllegalArgumentException("The center point " + centerPoint //$NON-NLS-1$
+                    + " of the original rectangle is out of the specified bounds."); //$NON-NLS-1$
+        }
+
+        double area = original.getWidth() * original.getHeight();
+
+        return createForCenterAreaAndRatioWithinBounds(centerPoint, area, ratio, bounds);
+    }
+
+    /*
+     * CENTER, AREA AND RATIO
+     */
+
+    /**
+     * Creates a new rectangle with the specified {@code centerPoint}, {@code area} and {@code ratio}.
+     * 
+     * @param centerPoint
+     *            the new rectangle's center point
+     * @param area
+     *            the new rectangle's area
+     * @param ratio
+     *            the new ratio
+     * @return a new {@link Rectangle2D} with the specified {@code centerPoint}, {@code area} and {@code ratio}
+     * @throws IllegalArgumentException
+     *             if the {@code centerPoint} is out of the {@code bounds}
+     */
+    public static Rectangle2D forCenterAndAreaAndRatio(Point2D centerPoint, double area, double ratio) {
+        Objects.requireNonNull(centerPoint, "The specified center point of the new rectangle must not be null."); //$NON-NLS-1$
+        if (area < 0) {
+            throw new IllegalArgumentException("The specified area " + area + " must be larger than zero."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if (ratio < 0) {
+            throw new IllegalArgumentException("The specified ratio " + ratio + " must be larger than zero."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return createForCenterAreaAndRatioWithinBounds(centerPoint, area, ratio, null);
+    }
+
+    /**
+     * Creates a new rectangle with the specified {@code centerPoint}, {@code area} (if possible) and {@code ratio},
+     * respecting the specified {@code bounds}.
+     * 
+     * @param centerPoint
+     *            the new rectangle's center point
+     * @param area
+     *            the new rectangle's area (if possible without violating the bounds)
+     * @param ratio
+     *            the new ratio
+     * @param bounds
+     *            the bounds within which the new rectangle will be located
+     * @return a new {@link Rectangle2D} with the specified {@code centerPoint} and {@code ratio}; it has the specified
+     *         {@code area} unless this would violate the {@code bounds}; in this case it is as large as possible while
+     *         still staying within the bounds
+     * @throws IllegalArgumentException
+     *             if the {@code centerPoint} is out of the {@code bounds}
+     */
+    public static Rectangle2D forCenterAndAreaAndRatioWithinBounds(
+            Point2D centerPoint, double area, double ratio, Rectangle2D bounds) {
+
+        Objects.requireNonNull(centerPoint, "The specified center point of the new rectangle must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(bounds, "The specified bounds for the new rectangle must not be null."); //$NON-NLS-1$
+        boolean centerPointInBounds = bounds.contains(centerPoint);
+        if (!centerPointInBounds) {
+            throw new IllegalArgumentException("The center point " + centerPoint //$NON-NLS-1$
+                    + " of the original rectangle is out of the specified bounds."); //$NON-NLS-1$
+        }
+        if (area < 0) {
+            throw new IllegalArgumentException("The specified area " + area + " must be larger than zero."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if (ratio < 0) {
+            throw new IllegalArgumentException("The specified ratio " + ratio + " must be larger than zero."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return createForCenterAreaAndRatioWithinBounds(centerPoint, area, ratio, bounds);
+    }
+
+    /**
+     * Creates a new rectangle with the specified {@code centerPoint}, {@code area} (if possible) and {@code ratio},
+     * respecting the specified {@code bounds} (if not-null).
+     * 
+     * @param centerPoint
+     *            the new rectangle's center point
+     * @param area
+     *            the new rectangle's area (if possible without violating the bounds)
+     * @param ratio
+     *            the new ratio
+     * @param bounds
+     *            the bounds within which the new rectangle will be located
+     * @return a new {@link Rectangle2D} with the specified {@code centerPoint} and {@code ratio}; it has the specified
+     *         {@code area} unless this would violate the {@code bounds}; in this case it is as large as possible while
+     *         still staying within the bounds
+     * @throws IllegalArgumentException
+     *             if the {@code centerPoint} is out of the {@code bounds}
+     */
+    private static Rectangle2D createForCenterAreaAndRatioWithinBounds(
+            Point2D centerPoint, double area, double ratio, Rectangle2D bounds) {
+
+        double newWidth = Math.sqrt(area * ratio);
+        double newHeight = area / newWidth;
+
+        boolean boundsSpecified = bounds != null;
+        if (boundsSpecified) {
+            double reductionFactor = lengthReductionToStayWithinBounds(centerPoint, newWidth, newHeight, bounds);
+            newWidth *= reductionFactor;
+            newHeight *= reductionFactor;
+        }
+
+        return Rectangles2D.forCenterAndSize(centerPoint, newWidth, newHeight);
+    }
+
+    /**
+     * Computes the factor by which the specified width and height must be multiplied to keep a rectangle with their
+     * ratio and the specified center point within the specified bounds.
+     * 
+     * @param centerPoint
+     *            the center point of the new rectangle
+     * @param width
+     *            the original width which might be too large
+     * @param height
+     *            the original height which might be too large
+     * @param bounds
+     *            the bounds within which the new rectangle will be located
+     * @return the factor with which the width and height must be multiplied to stay within the bounds; always in the
+     *         closed interval [0; 1]
+     * @throws IllegalArgumentException
+     *             if the {@code centerPoint} is out of the {@code bounds}; if {@code width} or {@code height} are not
+     *             larger than zero
+     */
+    private static double lengthReductionToStayWithinBounds(
+            Point2D centerPoint, double width, double height, Rectangle2D bounds) {
+
+        Objects.requireNonNull(centerPoint, "The specified center point of the new rectangle must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(bounds, "The specified bounds for the new rectangle must not be null."); //$NON-NLS-1$
+        boolean centerPointInBounds = bounds.contains(centerPoint);
+        if (!centerPointInBounds) {
+            throw new IllegalArgumentException("The center point " + centerPoint //$NON-NLS-1$
+                    + " of the original rectangle is out of the specified bounds."); //$NON-NLS-1$
+        }
+        if (width < 0) {
+            throw new IllegalArgumentException("The specified width " + width + " must be larger than zero."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if (height < 0) {
+            throw new IllegalArgumentException("The specified height " + height + " must be larger than zero."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        /*
+         * Compute the center point's distance to all edges. The width and height must be reduced (by the returned
+         * factor) such that their halves (!) are not greater than those distances. This can be done by finding the
+         * minimum ratio between the distance and the halved width/height.
+         */
+
+        double distanceToEast = Math.abs(centerPoint.getX() - bounds.getMinX());
+        double distanceToWest = Math.abs(centerPoint.getX() - bounds.getMaxX());
+        double distanceToNorth = Math.abs(centerPoint.getY() - bounds.getMinY());
+        double distanceToSouth = Math.abs(centerPoint.getY() - bounds.getMaxY());
+
+        // the returned factor must not be greater than one; otherwise the size would increase
+        return MathTools.min(1,
+                distanceToEast / width * 2, distanceToWest / width * 2,
+                distanceToNorth / height * 2, distanceToSouth / height * 2);
+    }
+
+    /*
+     * EDGES
+     */
+
+    /**
+     * Returns a rectangle that has the specified edge and has its opposing edge on the parallel axis defined by the
+     * specified point's X or Y coordinate (depending on the edge's orientation).
+     * 
+     * @param edge
+     *            the edge which will be contained in the returned rectangle
+     * @param point
+     *            the point whose X or Y coordinate defines the other edge
+     * @return a rectangle
+     */
+    public static Rectangle2D forEdgeAndOpposingPoint(Edge2D edge, Point2D point) {
+        double otherDimension = edge.getOrthogonalDifference(point);
+        return createForEdgeAndOtherDimension(edge, otherDimension);
+    }
+
+    /**
+     * Returns a rectangle that is principally defined by the specified edge and point. It should have the specified
+     * edge as one of its own and its parallel edge should contain the point. While this would already well-define the
+     * rectangle (compare {@link #forEdgeAndOpposingPoint(Edge2D, Point2D) forEdgeAndOpposingPoint}) the additionally
+     * specified ratio and bounds have precedence over these arguments:<br>
+     * The returned rectangle will have the ratio and will be within the bounds. If the bounds make it possible, the
+     * specified point will lie on the edge parallel to the specified one. In order to maintain the ratio, this will
+     * make it necessary to not use the specified edge but instead one with a different length. The new edge will have
+     * the same center point as the specified one.<br>
+     * This results on the following behavior: As the point is moved closer to or further away from the edge, the
+     * resulting rectangle shrinks and grows while being anchored to the specified edge's center point and keeping the
+     * ratio. This is limited by the bounds.
+     * 
+     * @param edge
+     *            the edge which defines the center point and orientation of one of the rectangle's edges; must be
+     *            within the specified {@code bounds}
+     * @param point
+     *            the point to which the rectangle spans if ratio and bounds allow it
+     * @param ratio
+     *            the ratio the new rectangle must have
+     * @param bounds
+     *            the bounds within which the new rectangle must lie
+     * @return a rectangle
+     */
+    public static Rectangle2D forEdgeAndOpposingPointAndRatioWithinBounds(
+            Edge2D edge, Point2D point, double ratio, Rectangle2D bounds) {
+
+        Objects.requireNonNull(edge, "The specified edge must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(point, "The specified point must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(bounds, "The specified bounds must not be null."); //$NON-NLS-1$
+
+        boolean edgeInBounds = contains(bounds, edge);
+        if (!edgeInBounds) {
+            throw new IllegalArgumentException(
+                    "The specified edge " + edge + " is not entirely contained on the specified bounds."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if (ratio < 0) {
+            throw new IllegalArgumentException("The specified ratio " + ratio + " must be larger than zero."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        /*
+         * 1. move the point into the bounds
+         * 2. create an edge whose length matches the distance to the point and the ratio
+         * 3. correct that edge so that it lies within the bounds
+         * 4. create a new rectangle from that edge and the ratio
+         */
+
+        Point2D boundedPoint = movePointIntoBounds(point, bounds);
+        Edge2D unboundedEdge = resizeEdgeForDistanceAndRatio(edge, boundedPoint, ratio);
+        Edge2D boundedEdge = resizeEdgeForBounds(unboundedEdge, bounds);
+
+        // when computing the other dimension, note that the sign of the original difference between edge and point is
+        // important; otherwise the "direction" of the resize is wrong
+        double otherDimension = Math.signum(boundedEdge.getOrthogonalDifference(boundedPoint));
+        if (boundedEdge.isHorizontal()) {
+            // edge horizontal -> width fixed -> use length to compute height
+            otherDimension *= boundedEdge.getLength() / ratio;
+        } else {
+            // edge vertical -> height fixed -> use length to compute width
+            otherDimension *= boundedEdge.getLength() * ratio;
+        }
+
+        return createForEdgeAndOtherDimension(boundedEdge, otherDimension);
+    }
+
+    /**
+     * Returns either the specified point if if the specified bounds {@link Rectangle2D#contains(Point2D) contain} it or
+     * a point whose X and/or Y coordinates are moved into the bounds.
+     * 
+     * @param point
+     *            the point to move into the {@code bounds}
+     * @param bounds
+     *            the bounds into which the {@code point} will be moved
+     * @return either {@code point} or a new {@link Point2D} whose coordinates were changed so that it lies within the
+     *         {@code bounds}
+     */
+    private static Point2D movePointIntoBounds(Point2D point, Rectangle2D bounds) {
+        if (bounds.contains(point)) {
+            return point;
+        } else {
+            double boundedPointX = MathTools.inInterval(bounds.getMinX(), point.getX(), bounds.getMaxX());
+            double boundedPointY = MathTools.inInterval(bounds.getMinY(), point.getY(), bounds.getMaxY());
+            return new Point2D(boundedPointX, boundedPointY);
+        }
+    }
+
+    /**
+     * Returns an edge with the same center point and orientation as the specified edge. Its length has the specified
+     * ratio to the distance of the edge and the specified point.
+     * 
+     * @param edge
+     *            the edge whose center point and orientation defines the returned edge's center point and orientation
+     * @param point
+     *            the point to which the distance is measured
+     * @param ratio
+     *            the ratio between the distance to the {@code point} and the returned edge's length
+     * @return an {@link Edge2D}
+     */
+    private static Edge2D resizeEdgeForDistanceAndRatio(Edge2D edge, Point2D point, double ratio) {
+        double distance = Math.abs(edge.getOrthogonalDifference(point));
+        if (edge.isHorizontal()) {
+            // a horizontal edge's length lies in the X axis; the distance lies in the Y axis: x = y * ratio
+            double xLength = distance * ratio;
+            return new Edge2D(edge.getCenterPoint(), edge.getOrientation(), xLength);
+        } else {
+            // a vertical edge's length lies in the Y axis; the distance lies in the X axis: y = x / ratio
+            double yLength = distance / ratio;
+            return new Edge2D(edge.getCenterPoint(), edge.getOrientation(), yLength);
+        }
+    }
+
+    /**
+     * Returns an edge with the same center point and orientation as the specified edge. If necessary, its length is
+     * reduced to fit within the bounds.
+     * 
+     * @param edge
+     *            the edge whose center point and orientation defines the returned edge's center point and orientation;
+     *            the center point must be within the bounds or an {@link IllegalArgumentException} will be thrown
+     * @param bounds
+     *            the bounds within which the returned edge must be contained
+     * @return either the specified {@code edge} if it is with in the {@code bounds} or one with a corrected length
+     * @throws IllegalArgumentException
+     *             if the {@code edge}'s center point is out of {@code bounds}
+     */
+    private static Edge2D resizeEdgeForBounds(Edge2D edge, Rectangle2D bounds) {
+        // return the same edge if it is in the bounds
+        boolean edgeInBounds = contains(bounds, edge);
+        if (edgeInBounds) {
+            return edge;
+        }
+
+        // make sure the bounds contain the edge's center point
+        boolean centerPointInBounds = bounds.contains(edge.getCenterPoint());
+        if (!centerPointInBounds) {
+            throw new IllegalArgumentException(
+                    "The specified edge's center point (" + edge + ") is out of the specified bounds (" + bounds + ")."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        if (edge.isHorizontal()) {
+            // compute the length bounds for the left and right part of the edge
+            double leftPartLengthBound = Math.abs(bounds.getMinX() - edge.getCenterPoint().getX());
+            double rightPartLengthBound = Math.abs(bounds.getMaxX() - edge.getCenterPoint().getX());
+            // compute the length of the left and right parts of the edge
+            double leftPartLength = MathTools.inInterval(0, edge.getLength() / 2, leftPartLengthBound);
+            double rightPartLength = MathTools.inInterval(0, edge.getLength() / 2, rightPartLengthBound);
+            // compute the total length as double of the smaller length
+            double horizontalLength = Math.min(leftPartLength, rightPartLength) * 2;
+            return new Edge2D(edge.getCenterPoint(), edge.getOrientation(), horizontalLength);
+        } else {
+            // compute the length bounds for the lower and upper part of the edge
+            double lowerPartLengthBound = Math.abs(bounds.getMinY() - edge.getCenterPoint().getY());
+            double upperPartLengthBound = Math.abs(bounds.getMaxY() - edge.getCenterPoint().getY());
+            // compute the length of the lower and upper part of the edge
+            double lowerPartLength = MathTools.inInterval(0, edge.getLength() / 2, lowerPartLengthBound);
+            double upperPartLength = MathTools.inInterval(0, edge.getLength() / 2, upperPartLengthBound);
+            // compute the total length as double of the smaller length
+            double verticalLength = Math.min(lowerPartLength, upperPartLength) * 2;
+            return new Edge2D(edge.getCenterPoint(), edge.getOrientation(), verticalLength);
+        }
+    }
+
+    /**
+     * Returns a rectangle that has the specified edge and a height or width (depending on the edge's orientation) as
+     * specified by {@code otherDimension}.
+     * 
+     * @param edge
+     *            the edge which will be contained in the returned rectangle
+     * @param otherDimension
+     *            if the edge's orientation is {@link Orientation#HORIZONTAL horizontal}, this is interpreted as the
+     *            height; if the edge's orientation is {@link Orientation#VERTICAL vertical}, this is interpreted as the
+     *            width
+     * @return a rectangle
+     */
+    private static Rectangle2D createForEdgeAndOtherDimension(Edge2D edge, double otherDimension) {
+        if (edge.isHorizontal()) {
+            return createForHorizontalEdgeAndHeight(edge, otherDimension);
+        } else {
+            return createForVerticalEdgeAndWidth(edge, otherDimension);
+        }
+    }
+
+    /**
+     * Returns a rectangle that has the specified horizontal edge and height. Depending on whether the width is positive
+     * or negative, the specified edge will be the upper or lower edge of the returned rectangle.
+     * 
+     * @param horizontalEdge
+     *            the horizontal edge which will be contained in the returned rectangle
+     * @param height
+     *            the returned rectangle's height
+     * @return a rectangle
+     */
+    private static Rectangle2D createForHorizontalEdgeAndHeight(Edge2D horizontalEdge, double height) {
+        Point2D leftEdgeEndPoint = horizontalEdge.getUpperLeft();
+        double upperLeftX = leftEdgeEndPoint.getX();
+        // if the height is negative, reduce the Y coordinate by that amount
+        double upperLeftY = leftEdgeEndPoint.getY() + Math.min(0, height);
+
+        double absoluteWidth = Math.abs(horizontalEdge.getLength());
+        double absoluteHeight = Math.abs(height);
+
+        return new Rectangle2D(upperLeftX, upperLeftY, absoluteWidth, absoluteHeight);
+    }
+
+    /**
+     * Returns a rectangle that has the specified horizontal edge and width. Depending on whether the width is positive
+     * or negative, the specified edge will be the left or right edge of the returned rectangle.
+     * 
+     * @param verticalEdge
+     *            the vertical edge which will be contained in the returned rectangle
+     * @param width
+     *            the returned rectangle's height
+     * @return a rectangle
+     */
+    private static Rectangle2D createForVerticalEdgeAndWidth(Edge2D verticalEdge, double width) {
+        Point2D upperEdgeEndPoint = verticalEdge.getUpperLeft();
+        // if the width is negative, reduce the X coordinate by that amount
+        double upperLeftX = upperEdgeEndPoint.getX() + Math.min(0, width);
+        double upperLeftY = upperEdgeEndPoint.getY();
+
+        double absoluteWidth = Math.abs(width);
+        double absoluteHeight = Math.abs(verticalEdge.getLength());
+
+        return new Rectangle2D(upperLeftX, upperLeftY, absoluteWidth, absoluteHeight);
+    }
+
+    /*
+     * MISC
+     */
+
+    /**
+     * Returns a rectangle with the same coordinates as the specified bounds.
+     * 
+     * @param bounds
+     *            the {@link Bounds} for which the rectangle will be created
+     * @return a {@link Rectangle2D} with the same minX-, minY-, maxX- and maxY-coordiantes as the specified bounds
+     */
+    public static Rectangle2D fromBounds(Bounds bounds) {
+        return new Rectangle2D(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight());
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/AbstractBeginEndCheckingChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/AbstractBeginEndCheckingChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..61e0e8238cc7301359f4b8098bc1c9dbc339cd9d
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/AbstractBeginEndCheckingChangeStrategy.java
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import java.util.Objects;
+
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * Abstract superclass to implementations of {@link Rectangle2DChangeStrategy}. Checks whether the specified points are not-null
+ * and the "begin-continue-end"-contract.
+ */
+abstract class AbstractBeginEndCheckingChangeStrategy implements Rectangle2DChangeStrategy {
+
+    // ATTRIBUTES
+
+    /**
+     * Indicates whether {@link #beginChange(Point2D) beginChange} was called.
+     */
+    private boolean beforeBegin;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a change strategy which checks whether begin and end are correctly called.
+     */
+    protected AbstractBeginEndCheckingChangeStrategy() {
+        beforeBegin = true;
+    }
+
+    // IMPLEMENTATION OF 'ChangeStrategy'
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final Rectangle2D beginChange(Point2D point) {
+        Objects.requireNonNull(point, "The specified point must not be null."); //$NON-NLS-1$
+        if (!beforeBegin)
+            throw new IllegalStateException(
+                    "The change already began, so 'beginChange' must not be called again before 'endChange' was called."); //$NON-NLS-1$
+        beforeBegin = false;
+
+        beforeBeginHook(point);
+        return doBegin(point);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final Rectangle2D continueChange(Point2D point) {
+        Objects.requireNonNull(point, "The specified point must not be null."); //$NON-NLS-1$
+        if (beforeBegin)
+            throw new IllegalStateException("The change did not begin. Call 'beginChange' before 'continueChange'."); //$NON-NLS-1$
+
+        return doContinue(point);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final Rectangle2D endChange(Point2D point) {
+        Objects.requireNonNull(point, "The specified point must not be null."); //$NON-NLS-1$
+        if (beforeBegin)
+            throw new IllegalStateException("The change did not begin. Call 'beginChange' before 'endChange'."); //$NON-NLS-1$
+
+        Rectangle2D finalRectangle = doEnd(point);
+        afterEndHook(point);
+        beforeBegin = true;
+        return finalRectangle;
+    }
+
+    //ABSTRACT METHODS
+
+    /**
+     * Called before the change begins at the specified point.
+     * 
+     * @param point
+     *            a point
+     */
+    protected void beforeBeginHook(Point2D point) {
+        // can be overridden by subclasses
+    }
+
+    /**
+     * Begins the change at the specified point.
+     * 
+     * @param point
+     *            a point
+     * @return the new rectangle
+     */
+    protected abstract Rectangle2D doBegin(Point2D point);
+
+    /**
+     * Continues the change to the specified point. Must not be called before a call to {@link #beginChange}.
+     * 
+     * @param point
+     *            a point
+     * @return the new rectangle
+     */
+    protected abstract Rectangle2D doContinue(Point2D point);
+
+    /**
+     * Ends the change at the specified point. Must not be called before a call to {@link #beginChange}.
+     * 
+     * @param point
+     *            a point
+     * @return the new rectangle
+     */
+    protected abstract Rectangle2D doEnd(Point2D point);
+
+    /**
+     * Called after the change ends at the specified point.
+     * 
+     * @param point
+     *            a point
+     */
+    protected void afterEndHook(Point2D point) {
+        // can be overridden by subclasses
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/AbstractFixedEdgeChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/AbstractFixedEdgeChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..ccc501941f6d49b0ddc427cd527995bba7cbee78
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/AbstractFixedEdgeChangeStrategy.java
@@ -0,0 +1,137 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import impl.org.controlsfx.tools.rectangle.Edge2D;
+import impl.org.controlsfx.tools.rectangle.Rectangles2D;
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * Abstract superclass to those implementations of {@link Rectangle2DChangeStrategy} which compute their rectangle by
+ * spanning it from a fixed edge to the parallel edge defined by the point given to
+ * {@link Rectangle2DChangeStrategy#continueChange(Point2D) continueChange}. <br>
+ * The edge is fixed during the change but can be changed in between changes. Implemented such that a ratio is respected
+ * if specified.
+ */
+abstract class AbstractFixedEdgeChangeStrategy extends AbstractRatioRespectingChangeStrategy {
+
+    // ATTRIBUTES
+
+    /**
+     * A rectangle which defines the bounds within which the new rectangle must be contained.
+     */
+    private final Rectangle2D bounds;
+
+    /**
+     * The edge which is fixed during the change. In {@link #doBegin(Point2D)} it is set to {@link #getFixedEdge()}; in
+     * {@link #doEnd(Point2D)} it is set to {@code null}.
+     */
+    private Edge2D fixedEdge;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a fixed edge change strategy. It respects the specified {@code ratio} if {@code ratioFixed} is
+     * {@code true}.
+     * 
+     * @param ratioFixed
+     *            indicates whether the ratio will be fixed
+     * @param ratio
+     *            defines the fixed ratio
+     * @param bounds
+     *            the bounds within which the new rectangle must be contained
+     */
+    protected AbstractFixedEdgeChangeStrategy(boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio);
+        this.bounds = bounds;
+    }
+
+    // ABSTRACT METHODS
+
+    /**
+     * Returns the edge which is fixed during the change. Called once when the change begins.
+     * 
+     * @return the edge which is fixed during the change
+     */
+    protected abstract Edge2D getFixedEdge();
+
+    // IMPLEMENTATION OF 'do...'
+
+    /**
+     * Creates a new rectangle from the two edges defined by {@link #fixedEdge} and its parallel through the specified
+     * point.
+     * 
+     * @param point
+     *            the point defining the parallel edge
+     * @return the rectangle defined the two edges
+     */
+    private final Rectangle2D createFromEdges(Point2D point) {
+        Point2D pointInBounds = Rectangles2D.inRectangle(bounds, point);
+
+        if (isRatioFixed()) {
+            return Rectangles2D.forEdgeAndOpposingPointAndRatioWithinBounds(
+                    fixedEdge, pointInBounds, getRatio(), bounds);
+        } else {
+            return Rectangles2D.forEdgeAndOpposingPoint(fixedEdge, pointInBounds);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected final Rectangle2D doBegin(Point2D point) {
+        boolean startPointNotInBounds = !bounds.contains(point);
+        if (startPointNotInBounds) {
+            throw new IllegalArgumentException(
+                    "The change's start point (" + point + ") must lie within the bounds (" + bounds + ")."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        fixedEdge = getFixedEdge();
+        return createFromEdges(point);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Rectangle2D doContinue(Point2D point) {
+        return createFromEdges(point);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected final Rectangle2D doEnd(Point2D point) {
+        Rectangle2D newRectangle = createFromEdges(point);
+        fixedEdge = null;
+        return newRectangle;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/AbstractFixedPointChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/AbstractFixedPointChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..27353e8abc7b40ebde80f7b4f63b1a1838bdf127
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/AbstractFixedPointChangeStrategy.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import impl.org.controlsfx.tools.rectangle.Rectangles2D;
+
+import java.util.Objects;
+
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * Abstract superclass to those implementations of {@link Rectangle2DChangeStrategy} which compute their rectangle by
+ * spanning it from a fixed point to the point given to {@link Rectangle2DChangeStrategy#continueChange(Point2D)
+ * continueChange}. <br>
+ * The point is fixed during the change but can be changed in between changes. Implemented such that a ratio is
+ * respected if specified.
+ */
+abstract class AbstractFixedPointChangeStrategy extends AbstractRatioRespectingChangeStrategy {
+
+    // ATTRIBUTES
+
+    /**
+     * A rectangle which defines the bounds within which the new rectangle must be contained.
+     */
+    private final Rectangle2D bounds;
+
+    /**
+     * The point which is fixed during the change. In {@link #doBegin(Point2D)} it is set to {@link #getFixedCorner()};
+     * in {@link #doEnd(Point2D)} it is set to {@code null}.
+     */
+    private Point2D fixedCorner;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a fixed corner change strategy. It respects the specified {@code ratio} if {@code ratioFixed} is
+     * {@code true}.
+     * 
+     * @param ratioFixed
+     *            indicates whether the ratio will be fixed
+     * @param ratio
+     *            defines the fixed ratio
+     * @param bounds
+     *            the bounds within which the new rectangle must be contained
+     */
+    protected AbstractFixedPointChangeStrategy(boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio);
+        Objects.requireNonNull(bounds, "The argument 'bounds' must not be null."); //$NON-NLS-1$
+
+        this.bounds = bounds;
+    }
+
+    // ABSTRACT METHODS
+
+    /**
+     * Returns the corner which is fixed during the change. Called once when the change begins.
+     * 
+     * @return the corner which is fixed during the change
+     */
+    protected abstract Point2D getFixedCorner();
+
+    // IMPLEMENTATION OF 'do...'
+
+    /**
+     * Creates a new rectangle from the two corners defined by {@link #getFixedCorner()} and the specified point.
+     * 
+     * @param point
+     *            the second corner
+     * @return the rectangle defined the two corners
+     */
+    private final Rectangle2D createFromCorners(Point2D point) {
+        Point2D pointInBounds = Rectangles2D.inRectangle(bounds, point);
+
+        if (isRatioFixed()) {
+            return Rectangles2D.forDiagonalCornersAndRatio(fixedCorner, pointInBounds, getRatio());
+        } else {
+            return Rectangles2D.forDiagonalCorners(fixedCorner, pointInBounds);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected final Rectangle2D doBegin(Point2D point) {
+        boolean startPointNotInBounds = !bounds.contains(point);
+        if (startPointNotInBounds) {
+            throw new IllegalArgumentException(
+                    "The change's start point (" + point + ") must lie within the bounds (" + bounds + ")."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        fixedCorner = getFixedCorner();
+        return createFromCorners(point);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Rectangle2D doContinue(Point2D point) {
+        return createFromCorners(point);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected final Rectangle2D doEnd(Point2D point) {
+        Rectangle2D newRectangle = createFromCorners(point);
+        fixedCorner = null;
+        return newRectangle;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/AbstractPreviousRectangleChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/AbstractPreviousRectangleChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf169d339c9fbc74589775dd4a56ae6b52a0ec20
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/AbstractPreviousRectangleChangeStrategy.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import java.util.Objects;
+
+import javafx.geometry.Rectangle2D;
+
+/**
+ * Abstract superclass to those implementations of {@link Rectangle2DChangeStrategy}, which are based on a previous
+ * rectangle. Respects a ratio if one is set.
+ */
+abstract class AbstractPreviousRectangleChangeStrategy extends AbstractRatioRespectingChangeStrategy {
+
+    // ATTRIBUTES
+
+    /**
+     * The rectangle these changes are based on.
+     */
+    private final Rectangle2D previous;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a change strategy which is based on the specified {@code previous} rectangle and respects the specified
+     * {@code ratio} if {@code ratioFixed} is {@code true}.
+     * 
+     * @param previous
+     *            the previous rectangle this change is based on
+     * @param ratioFixed
+     *            indicates whether the ratio will be fixed
+     * @param ratio
+     *            defines the fixed ratio
+     */
+    protected AbstractPreviousRectangleChangeStrategy(Rectangle2D previous, boolean ratioFixed, double ratio) {
+        super(ratioFixed, ratio);
+
+        Objects.requireNonNull(previous, "The previous rectangle must not be null."); //$NON-NLS-1$
+        this.previous = previous;
+    }
+
+    // ATTRIBUTE ACCESS
+
+    /**
+     * The previous rectangle this change is based on.
+     * 
+     * @return the previous rectangle
+     */
+    protected final Rectangle2D getPrevious() {
+        return previous;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/AbstractRatioRespectingChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/AbstractRatioRespectingChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d89c73e73074bafe54de2aeb064b0222238fe82
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/AbstractRatioRespectingChangeStrategy.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+/**
+ * Abstract superclass to implementations of {@link Rectangle2DChangeStrategy}, which might be parameterized such that only
+ * rectangles of a defined ratio are created. This parameterization happens during construction. Subclasses must
+ * implement the ratio handling themselves! This class only holds the parameters.
+ */
+abstract class AbstractRatioRespectingChangeStrategy extends AbstractBeginEndCheckingChangeStrategy {
+
+    // ATTRIBUTES
+
+    /**
+     * Indicates whether the current selection must have a fixed ratio. If so, 'ratio' can be used.
+     */
+    private final boolean ratioFixed;
+
+    /**
+     * The currently used ratio. Should only be used if 'ratioFixed' is true.
+     */
+    private final double ratio;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a change strategy which respects the specified {@code ratio} if {@code ratioFixed} is {@code true}.
+     * 
+     * @param ratioFixed
+     *            indicates whether the ratio will be fixed
+     * @param ratio
+     *            defines the fixed ratio
+     */
+    protected AbstractRatioRespectingChangeStrategy(boolean ratioFixed, double ratio) {
+        super();
+        this.ratioFixed = ratioFixed;
+        this.ratio = ratio;
+    }
+
+    // Attribute Access
+
+    /**
+     * Indicates whether the ratio is fixed. If so, the ratio can be accessed with {@link #getRatio()}.
+     * 
+     * @return true if the ratio is fixed; false otherwise
+     */
+    protected final boolean isRatioFixed() {
+        return ratioFixed;
+    }
+
+    /**
+     * The current ratio. Can only be called without exception when {@link #isRatioFixed()} returns true.
+     * 
+     * @return the current ratio
+     */
+    protected final double getRatio() {
+        if (!ratioFixed)
+            throw new IllegalStateException("The ratio is not fixed."); //$NON-NLS-1$
+        return ratio;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/MoveChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/MoveChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..26f8c9dc5c156c4d5841b830d2c12c5495507eec
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/MoveChangeStrategy.java
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import impl.org.controlsfx.tools.MathTools;
+
+import java.util.Objects;
+
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * Moves the rectangle around.
+ */
+public class MoveChangeStrategy extends AbstractPreviousRectangleChangeStrategy {
+
+    /*
+     * The previous rectangle will be moved around using a vector computed from the start to the current point.
+     * The moved rectangle will be forced within defined bounds.
+     */
+
+    // ATTRIBUTES
+
+    /**
+     * A rectangle which defines the bounds within which the previous rectangle can be moved.
+     */
+    private final Rectangle2D bounds;
+
+    /**
+     * The starting point of the selection change. The move will be computed relative to this point.
+     */
+    private Point2D startingPoint;
+
+    // CONSTRUCTORS
+
+    /**
+     * Creates a new change strategy which moves the specified rectangle within the specified bounds.
+     * 
+     * @param previous
+     *            the previous rectangle this move is based on
+     * @param bounds
+     *            the bounds within which the rectangle can be moved
+     */
+    public MoveChangeStrategy(Rectangle2D previous, Rectangle2D bounds) {
+        super(previous, false, 0);
+        Objects.requireNonNull(bounds, "The specified bounds must not be null."); //$NON-NLS-1$
+        this.bounds = bounds;
+    }
+
+    /**
+     * Creates a new change strategy which moves the specified rectangle within the specified bounds defined by the
+     * rectangle from {@code (0, 0)} to {@code (maxX, maxY)}.
+     * 
+     * @param previous
+     *            the previous rectangle this move is based on
+     * @param maxX
+     *            the maximal x-coordinate of the right edge of the created rectangles; must be greater than or equal to
+     *            the previous rectangle's width
+     * @param maxY
+     *            the maximal y-coordinate of the lower edge of the created rectangles; must be greater than or equal to
+     *            the previous rectangle's height
+     */
+    public MoveChangeStrategy(Rectangle2D previous, double maxX, double maxY) {
+        super(previous, false, 0);
+        if (maxX < previous.getWidth()) {
+            throw new IllegalArgumentException(
+                    "The specified maximal x-coordinate must be greater than or equal to the previous rectangle's width."); //$NON-NLS-1$
+        }
+        if (maxY < previous.getHeight()) {
+            throw new IllegalArgumentException(
+                    "The specified maximal y-coordinate must be greater than or equal to the previous rectangle's height."); //$NON-NLS-1$
+        }
+
+        bounds = new Rectangle2D(0, 0, maxX, maxY);
+    }
+
+    // IMPLEMENTATION OF 'do...'
+
+    /**
+     * Moves the previous rectangle to the specified point relative to the {@link #startingPoint}.
+     * 
+     * @param point
+     *            the vector from the {@link #startingPoint} to this point defines the movement
+     * @return the moved rectangle
+     */
+    private final Rectangle2D moveRectangleToPoint(Point2D point) {
+
+        /*
+         * The computation makes sure that no part of the rectangle can be moved out the bounds.
+         * To achieve this, the coordinates of the future rectangle's upper left corner are forced into the intervals
+         *  - [boundsMinX, boundsMaxX - previousRectangleWidth],
+         *  - [boundsMinY, boundsMaxY - previousRectangleHeight] respectively.
+         */
+
+        // vector from starting to specified point
+        double xMove = point.getX() - startingPoint.getX();
+        double yMove = point.getY() - startingPoint.getY();
+
+        // upper left corner
+        double upperLeftX = getPrevious().getMinX() + xMove;
+        double upperLeftY = getPrevious().getMinY() + yMove;
+
+        // upper bounds for upper left corner
+        double maxX = bounds.getMaxX() - getPrevious().getWidth();
+        double maxY = bounds.getMaxY() - getPrevious().getHeight();
+
+        // corrected upper left corner
+        double correctedUpperLeftX = MathTools.inInterval(bounds.getMinX(), upperLeftX, maxX);
+        double correctedUpperLeftY = MathTools.inInterval(bounds.getMinY(), upperLeftY, maxY);
+
+        // rectangle from corrected upper left corner with the previous rectangle's width and height
+        return new Rectangle2D(
+                correctedUpperLeftX, correctedUpperLeftY,
+                getPrevious().getWidth(), getPrevious().getHeight());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Rectangle2D doBegin(Point2D point) {
+        this.startingPoint = point;
+        return getPrevious();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Rectangle2D doContinue(Point2D point) {
+        return moveRectangleToPoint(point);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Rectangle2D doEnd(Point2D point) {
+        return moveRectangleToPoint(point);
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/NewChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/NewChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..e62f4b4ed74b7dab375f38fe131fa7cbb0dac2e7
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/NewChangeStrategy.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * A strategy which creates a new rectangle.
+ */
+public class NewChangeStrategy extends AbstractFixedPointChangeStrategy {
+
+    /*
+     * The new selection will have the starting point as a fixed corner. The other corner will always be the current
+     * point modulo the ratio which will be respected if enforced. Both is handled by the superclass.
+     */
+
+    // ATTRIBUTES
+
+    /**
+     * The starting point of this change.
+     */
+    private Point2D startingPoint;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a change strategy which creates a new rectangle. It respects the specified {@code ratio} if
+     * {@code ratioFixed} is {@code true}.
+     * 
+     * @param ratioFixed
+     *            indicates whether the ratio will be fixed
+     * @param ratio
+     *            defines the fixed ratio
+     * @param bounds
+     *            the bounds within which the new rectangle must be contained
+     */
+    public NewChangeStrategy(boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio, bounds);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void beforeBeginHook(Point2D point) {
+        startingPoint = point;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Point2D getFixedCorner() {
+        return startingPoint;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/Rectangle2DChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/Rectangle2DChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..378410670ade149778b9fb8c709c2fdccc780eb1
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/Rectangle2DChangeStrategy.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * A {@code Rectangle2DChangeStrategy} creates instances of {@link Rectangle2D} based on the coordinates of the begin,
+ * continuation and end of an action. The behavior is undefined if these three methods are not called on the following
+ * order:<br>
+ * ({@link #beginChange(Point2D) begin} -> {@link #continueChange(Point2D) continue}* -> {@link #endChange(Point2D) end}
+ * )* <br>
+ * <br>
+ * Most implementations will be creating new rectangles based on an existing one. If the created ones constantly replace
+ * the original, this effectively "changes" the rectangle's appearance (note that {@link Rectangle2D} instances
+ * themselves are immutable !). This interface and its implementations were created to easily allow a GUI user to change
+ * an existing rectangle by typical resize and move operations.
+ */
+public interface Rectangle2DChangeStrategy {
+
+    /**
+     * Begins the change at the specified point.
+     * 
+     * @param point
+     *            a point
+     * @return the new rectangle
+     */
+    Rectangle2D beginChange(Point2D point);
+
+    /**
+     * Continues the change to the specified point. Must not be called before a call to {@link #beginChange}.
+     * 
+     * @param point
+     *            a point
+     * @return the new rectangle
+     */
+    Rectangle2D continueChange(Point2D point);
+
+    /**
+     * Ends the change at the specified point. Must not be called before a call to {@link #beginChange}.
+     * 
+     * @param point
+     *            a point
+     * @return the new rectangle
+     */
+    Rectangle2D endChange(Point2D point);
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/ToEastChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/ToEastChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..ccbe662ee1447c7a4a1b0167a98710fb5d1c935c
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/ToEastChangeStrategy.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import impl.org.controlsfx.tools.rectangle.Edge2D;
+import javafx.geometry.Orientation;
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * A strategy which enlarges an existing rectangle to the east.
+ */
+public class ToEastChangeStrategy extends AbstractFixedEdgeChangeStrategy {
+
+    /*
+     * The new rectangle will have the existing rectangle's western edge as a fixed edge. The parallel edge will
+     * be defined by the current point (modulo the ratio which will be respected if enforced), which is handled by the
+     * superclass.
+     */
+
+    // ATTRIBUTES
+
+    /**
+     * The new rectangle's western edge.
+     */
+    private final Edge2D westernEdge;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the east. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param bounds
+     *            the bounds within which the rectangle can be resized
+     */
+    public ToEastChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio, bounds);
+        Point2D edgeCenterPoint = new Point2D(original.getMinX(), (original.getMinY() + original.getMaxY()) / 2);
+        westernEdge = new Edge2D(edgeCenterPoint, Orientation.VERTICAL, original.getMaxY() - original.getMinY());
+    }
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the northeast. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param maxX
+     *            the maximal x-coordinate of the right edge of the created rectangles; must be greater than or equal to
+     *            the previous rectangle's width
+     * @param maxY
+     *            the maximal y-coordinate of the lower edge of the created rectangles; must be greater than or equal to
+     *            the previous rectangle's height
+     */
+    public ToEastChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, double maxX, double maxY) {
+        this(original, ratioFixed, ratio, new Rectangle2D(0, 0, maxX, maxY));
+    }
+
+    // IMPLEMENTATION OF 'AbstractFixedEdgeChangeStrategy'
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Edge2D getFixedEdge() {
+        return westernEdge;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/ToNorthChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/ToNorthChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..29674d0f4254edcd96599c383e0125c9875d2caf
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/ToNorthChangeStrategy.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import impl.org.controlsfx.tools.rectangle.Edge2D;
+import javafx.geometry.Orientation;
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * A strategy which enlarges an existing rectangle to the north.
+ */
+public class ToNorthChangeStrategy extends AbstractFixedEdgeChangeStrategy {
+
+    /*
+     * The new rectangle will have the existing rectangle's southern edge as a fixed edge. The parallel edge will
+     * be defined by the current point (modulo the ratio which will be respected if enforced), which is handled by the
+     * superclass.
+     */
+
+    // ATTRIBUTES
+
+    /**
+     * The new rectangle's southern edge.
+     */
+    private final Edge2D southernEdge;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the north. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param bounds
+     *            the bounds within which the rectangle can be resized
+     */
+    public ToNorthChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio, bounds);
+        Point2D edgeCenterPoint = new Point2D((original.getMinX() + original.getMaxX()) / 2, original.getMaxY());
+        southernEdge = new Edge2D(edgeCenterPoint, Orientation.HORIZONTAL, original.getMaxX() - original.getMinX());
+    }
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the northeast. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param maxX
+     *            the maximal x-coordinate of the right edge of the created rectangles; must be greater than or equal to
+     *            the previous rectangle's width
+     * @param maxY
+     *            the maximal y-coordinate of the lower edge of the created rectangles; must be greater than or equal to
+     *            the previous rectangle's height
+     */
+    public ToNorthChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, double maxX, double maxY) {
+        this(original, ratioFixed, ratio, new Rectangle2D(0, 0, maxX, maxY));
+    }
+
+    // IMPLEMENTATION OF 'AbstractFixedEdgeChangeStrategy'
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Edge2D getFixedEdge() {
+        return southernEdge;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/ToNortheastChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/ToNortheastChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..5edb288151ac4f27a3538fecaa73fc602da8ef0a
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/ToNortheastChangeStrategy.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * A strategy which enlarges an existing rectangle to the northeast.
+ */
+public class ToNortheastChangeStrategy extends AbstractFixedPointChangeStrategy {
+
+    /*
+     * The new rectangle will have the existing rectangle's southwestern corner as a fixed corner. The other corner will
+     * always be the current point (modulo the ratio which will be respected if enforced), which is handled by the
+     * superclass.
+     */
+
+    // ATTRIBUTES
+
+    /**
+     * The new rectangle's southwestern corner.
+     */
+    private final Point2D southwesternCorner;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the northeast. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param bounds
+     *            the bounds within which the new rectangle must be contained
+     */
+    public ToNortheastChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio, bounds);
+        southwesternCorner = new Point2D(original.getMinX(), original.getMaxY());
+    }
+
+    // IMPLEMENTATION OF 'AbstractFixedPointChangeStrategy'
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Point2D getFixedCorner() {
+        return southwesternCorner;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/ToNorthwestChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/ToNorthwestChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..183133367ee4289d13ffc61e6435ea82d9bf664e
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/ToNorthwestChangeStrategy.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * A strategy which enlarges an existing rectangle to the northwest.
+ */
+public class ToNorthwestChangeStrategy extends AbstractFixedPointChangeStrategy {
+
+    /*
+     * The new rectangle will have the existing rectangle's southeastern corner as a fixed corner. The other corner will
+     * always be the current point (modulo the ratio which will be respected if enforced), which is handled by the
+     * superclass.
+     */
+
+    // ATTRIBUTES
+
+    /**
+     * The new rectangle's southeastern corner.
+     */
+    private final Point2D southeasternCorner;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the northwest. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param bounds
+     *            the bounds within which the new rectangle must be contained
+     */
+    public ToNorthwestChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio, bounds);
+        southeasternCorner = new Point2D(original.getMaxX(), original.getMaxY());
+    }
+
+    // IMPLEMENTATION OF 'AbstractFixedPointChangeStrategy'
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Point2D getFixedCorner() {
+        return southeasternCorner;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/ToSouthChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/ToSouthChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ea9f78ea185543f2d340c2fa17016cf0190bc94
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/ToSouthChangeStrategy.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import impl.org.controlsfx.tools.rectangle.Edge2D;
+import javafx.geometry.Orientation;
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * A strategy which enlarges an existing rectangle to the south.
+ */
+public class ToSouthChangeStrategy extends AbstractFixedEdgeChangeStrategy {
+
+    /*
+     * The new rectangle will have the existing rectangle's northern edge as a fixed edge. The parallel edge will
+     * be defined by the current point (modulo the ratio which will be respected if enforced), which is handled by the
+     * superclass.
+     */
+
+    // ATTRIBUTES
+
+    /**
+     * The new rectangle's northern edge.
+     */
+    private final Edge2D northernEdge;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the south. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param bounds
+     *            the bounds within which the rectangle can be resized
+     */
+    public ToSouthChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio, bounds);
+        Point2D edgeCenterPoint = new Point2D((original.getMinX() + original.getMaxX()) / 2, original.getMinY());
+        northernEdge = new Edge2D(edgeCenterPoint, Orientation.HORIZONTAL, original.getMaxX() - original.getMinX());
+    }
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the northeast. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param maxX
+     *            the maximal x-coordinate of the right edge of the created rectangles; must be greater than or equal to
+     *            the previous rectangle's width
+     * @param maxY
+     *            the maximal y-coordinate of the lower edge of the created rectangles; must be greater than or equal to
+     *            the previous rectangle's height
+     */
+    public ToSouthChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, double maxX, double maxY) {
+        this(original, ratioFixed, ratio, new Rectangle2D(0, 0, maxX, maxY));
+    }
+
+    // IMPLEMENTATION OF 'AbstractFixedEdgeChangeStrategy'
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Edge2D getFixedEdge() {
+        return northernEdge;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/ToSoutheastChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/ToSoutheastChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..430c3f5b2db94b8bc61b974d34c4df84dd035f60
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/ToSoutheastChangeStrategy.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * A strategy which enlarges an existing rectangle to the southeast.
+ */
+public class ToSoutheastChangeStrategy extends AbstractFixedPointChangeStrategy {
+
+    /*
+     * The new rectangle will have the existing rectangle's northwestern corner as a fixed corner. The other corner will
+     * always be the current point (modulo the ratio which will be respected if enforced), which is handled by the
+     * superclass.
+     */
+
+    // ATTRIBUTES
+
+    /**
+     * The new rectangle's northwestern corner.
+     */
+    private final Point2D northwesternCorner;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the southeast. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param bounds
+     *            the bounds within which the new rectangle must be contained
+     */
+    public ToSoutheastChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio, bounds);
+        northwesternCorner = new Point2D(original.getMinX(), original.getMinY());
+    }
+
+    // IMPLEMENTATION OF 'AbstractFixedPointChangeStrategy'
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Point2D getFixedCorner() {
+        return northwesternCorner;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/ToSouthwestChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/ToSouthwestChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..cad2aeee18f553e2360304012d594d5f5c900e91
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/ToSouthwestChangeStrategy.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * A strategy which enlarges an existing rectangle to the southwest.
+ * 
+ * @author pan
+ */
+public class ToSouthwestChangeStrategy extends AbstractFixedPointChangeStrategy {
+
+    /*
+     * The new rectangle will have the existing rectangle's northeastern corner as a fixed corner. The other corner will
+     * always be the current point (modulo the ratio which will be respected if enforced), which is handled by the
+     * superclass.
+     */
+
+    // ATTRIBUTES
+
+    /**
+     * The new rectangle's northeastern corner.
+     */
+    private final Point2D northeasternCorner;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the southwest. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param bounds
+     *            the bounds within which the new rectangle must be contained
+     */
+    public ToSouthwestChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio, bounds);
+        northeasternCorner = new Point2D(original.getMaxX(), original.getMinY());
+    }
+
+    // IMPLEMENTATION OF 'AbstractFixedPointChangeStrategy'
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Point2D getFixedCorner() {
+        return northeasternCorner;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/tools/rectangle/change/ToWestChangeStrategy.java b/src/impl/org/controlsfx/tools/rectangle/change/ToWestChangeStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..4500992c6db9dc3a3e8c4ba5da3d54c9b8d29d7e
--- /dev/null
+++ b/src/impl/org/controlsfx/tools/rectangle/change/ToWestChangeStrategy.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.tools.rectangle.change;
+
+import impl.org.controlsfx.tools.rectangle.Edge2D;
+import javafx.geometry.Orientation;
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+
+/**
+ * A strategy which enlarges an existing rectangle to the west.
+ */
+public class ToWestChangeStrategy extends AbstractFixedEdgeChangeStrategy {
+
+    /*
+     * The new rectangle will have the existing rectangle's eastern edge as a fixed edge. The parallel edge will
+     * be defined by the current point (modulo the ratio which will be respected if enforced), which is handled by the
+     * superclass.
+     */
+
+    // ATTRIBUTES
+
+    /**
+     * The new rectangle's eastern edge.
+     */
+    private final Edge2D easternEdge;
+
+    // CONSTRUCTOR
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the west. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param bounds
+     *            the bounds within which the rectangle can be resized
+     */
+    public ToWestChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, Rectangle2D bounds) {
+        super(ratioFixed, ratio, bounds);
+        Point2D edgeCenterPoint = new Point2D(original.getMaxX(), (original.getMinY() + original.getMaxY()) / 2);
+        easternEdge = new Edge2D(edgeCenterPoint, Orientation.VERTICAL, original.getMaxY() - original.getMinY());
+    }
+
+    /**
+     * Creates a new change strategy which enlarges the specified {@code original} rectangle to the northeast. The given
+     * {@code ratio} is enforced when indicated by {@code ratioFixed}.
+     * 
+     * @param original
+     *            the original rectangle
+     * @param ratioFixed
+     *            indicates whether the rectangle's ratio will be fixed to the {@code ratio}
+     * @param ratio
+     *            the possibly fixed ratio of the rectangle created by this strategy
+     * @param maxX
+     *            the maximal x-coordinate of the right edge of the created rectangles; must be greater than or equal to
+     *            the previous rectangle's width
+     * @param maxY
+     *            the maximal y-coordinate of the lower edge of the created rectangles; must be greater than or equal to
+     *            the previous rectangle's height
+     */
+    public ToWestChangeStrategy(Rectangle2D original, boolean ratioFixed, double ratio, double maxX, double maxY) {
+        this(original, ratioFixed, ratio, new Rectangle2D(0, 0, maxX, maxY));
+    }
+
+    // IMPLEMENTATION OF 'AbstractFixedEdgeChangeStrategy'
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Edge2D getFixedEdge() {
+        return easternEdge;
+    }
+
+}
diff --git a/src/impl/org/controlsfx/version/VersionChecker.java b/src/impl/org/controlsfx/version/VersionChecker.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e91d0f8d8dd8af36187e48d7fa893abccc6b2de
--- /dev/null
+++ b/src/impl/org/controlsfx/version/VersionChecker.java
@@ -0,0 +1,222 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package impl.org.controlsfx.version;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Properties;
+
+import com.sun.javafx.runtime.VersionInfo;
+
+public class VersionChecker {
+    
+    private static final String javaFXVersion;
+    private static final String controlsFXSpecTitle;
+    private static final String controlsFXSpecVersion;
+    private static final String controlsFXImpVersion;
+    
+    private static final Package controlsFX;
+    
+    private static Properties props;
+    
+    static {
+        controlsFX = VersionChecker.class.getPackage();
+        
+        javaFXVersion         = VersionInfo.getVersion();
+        controlsFXSpecTitle   = getControlsFXSpecificationTitle();
+        controlsFXSpecVersion = getControlsFXSpecificationVersion();
+        controlsFXImpVersion  = getControlsFXImplementationVersion();
+    }
+
+    private VersionChecker() {
+        // no-op
+    }
+    
+    public static void doVersionCheck() {
+        // We keep ControlsFX bleeding edge, and we try to let our version numbers
+        // do the talking. However, we can't always ensure people do the right 
+        // thing, so here we will check the ControlsFX and JavaFX version numbers,
+        // to ensure they match.
+        // Fortunately, our system is simple at present: we use the
+        // 'controlsFXSpec' value to represent what we require. In other
+        // words, ControlsFX 8.0.0 has controlsFXSpecVersion of 8.0.0, so it will work on 
+        // JavaFX 8.0.0 and later versions. Conversely, ControlsFX 8.0.6_20 has a controlsFXSpecVersion of
+        // 8.0.20 (controlsFXSpecTitle of Java 8u20), which means that ControlsFX will only work on JavaFX 8u20
+        // and later versions.
+        
+        if (controlsFXSpecVersion == null) {
+            // FIXME temporary fix to allow ControlsFX to work when run inside
+            // an IDE (i.e. for developers of ControlsFX).
+            return;
+        }
+        
+        Comparable[] splitSpecVersion = toComparable(controlsFXSpecVersion.split("\\.")); //$NON-NLS-1$
+        
+        // javaFXVersion may contain '-' like 8.0.20-ea so replace them with '.' before splitting.
+        Comparable[] splitJavaVersion = toComparable(javaFXVersion.replace('-', '.').split("\\.")); //$NON-NLS-1$
+
+        boolean notSupportedVersion = false;
+
+        // Check Major Version
+        if (splitSpecVersion[0].compareTo(splitJavaVersion[0]) > 0) {
+            notSupportedVersion = true;
+        } else if (splitSpecVersion[0].compareTo(splitJavaVersion[0]) == 0) {
+            // Check Minor Version
+            if (splitSpecVersion[1].compareTo(splitJavaVersion[2])>0) {
+                notSupportedVersion = true;
+            }
+        }
+
+        if (notSupportedVersion) {
+            throw new RuntimeException("ControlsFX Error: ControlsFX " + //$NON-NLS-1$
+                controlsFXImpVersion + " requires at least " + controlsFXSpecTitle); //$NON-NLS-1$
+        }
+    }
+
+    private static Comparable<Comparable>[] toComparable(String[] tokens) {
+        Comparable[] ret= new Comparable[tokens.length];
+        for (int i = 0; i<tokens.length; i++) {
+            String token = tokens[i];
+            try {
+                ret[i] = new Integer(token);
+            }
+            catch (NumberFormatException e) {
+                ret[i] = token;
+            }
+        }
+        return ret;
+    }
+
+    private static String getControlsFXSpecificationTitle() {
+        // firstly try to read from manifest
+        try {
+            return controlsFX.getSpecificationTitle();
+        } catch (NullPointerException e) {
+            // no-op
+        }
+        
+        // try to read it from the controlsfx-build.properties if running
+        // from within an IDE
+        return getPropertyValue("controlsfx_specification_title"); //$NON-NLS-1$
+        
+        
+//        try {
+//            Properties prop = new Properties();
+//            File file = new File("../controlsfx-build.properties");
+//            if (file.exists()) {
+//                prop.load(new FileReader(file));
+//                String version = prop.getProperty("controlsfx_specification_title");
+//                if (version != null && !version.isEmpty()) {
+//                    return version;
+//                }
+//            }
+//        } catch (IOException e) {
+//            // no-op
+//        }
+//        
+//        return null;
+    }
+    
+    private static String getControlsFXSpecificationVersion() {
+        
+        // firstly try to read from manifest
+        try {
+            return controlsFX.getSpecificationVersion();
+        } catch (NullPointerException e) {
+            // no-op
+        }
+        
+        // try to read it from the controlsfx-build.properties if running
+        // from within an IDE
+        return getPropertyValue("controlsfx_specification_title"); //$NON-NLS-1$
+        
+//        try {
+//            Properties prop = new Properties();
+//            File file = new File("../controlsfx-build.properties");
+//            if (file.exists()) {
+//                prop.load(new FileReader(file));
+//                String version = prop.getProperty("controlsfx_specification_version");
+//                if (version != null && !version.isEmpty()) {
+//                    return version;
+//                }
+//            }
+//        } catch (IOException e) {
+//            // no-op
+//        }
+//        
+//        return null;
+    }
+    
+    private static String getControlsFXImplementationVersion() {
+        
+        // firstly try to read from manifest
+        try {
+            return controlsFX.getImplementationVersion();
+        } catch (NullPointerException e) {
+            // no-op
+        }
+        
+        // try to read it from the controlsfx-build.properties if running
+        // from within an IDE
+        
+        return getPropertyValue("controlsfx_specification_title") + //$NON-NLS-1$
+        	   getPropertyValue("artifact_suffix"); //$NON-NLS-1$
+        
+        
+//        try {
+//            Properties prop = new Properties();
+//            File file = new File("../controlsfx-build.properties");
+//            if (file.exists()) {
+//                prop.load(new FileReader(file));
+//                String version = prop.getProperty("controlsfx_version");
+//                if (version != null && !version.isEmpty()) {
+//                    return version;
+//                }
+//            }
+//        } catch (IOException e) {
+//            // no-op
+//        }
+//        
+//        return null;
+    }
+    
+    private static synchronized String getPropertyValue(String key) {
+    	
+    	if ( props == null ) {
+        	try {
+                File file = new File("../controlsfx-build.properties"); //$NON-NLS-1$
+                if (file.exists()) {
+                    props.load(new FileReader(file));
+                }
+            } catch (IOException e) {
+                // no-op
+            }
+    	}
+    	return props.getProperty(key);
+    }
+}
diff --git a/src/org/controlsfx/control/BreadCrumbBar.java b/src/org/controlsfx/control/BreadCrumbBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..38bfe10c8cba2c15aae02a85107f354ac4c7bc27
--- /dev/null
+++ b/src/org/controlsfx/control/BreadCrumbBar.java
@@ -0,0 +1,343 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.BreadCrumbBarSkin;
+import impl.org.controlsfx.skin.BreadCrumbBarSkin.BreadCrumbButton;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ObjectPropertyBase;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.event.Event;
+import javafx.event.EventDispatchChain;
+import javafx.event.EventHandler;
+import javafx.event.EventType;
+import javafx.scene.control.Button;
+import javafx.scene.control.Skin;
+import javafx.scene.control.TreeItem;
+import javafx.util.Callback;
+
+import com.sun.javafx.event.EventHandlerManager;
+
+/**
+ * Represents a bread crumb bar. This control is useful to visualize and navigate 
+ * a hierarchical path structure, such as file systems.
+ * 
+ * <p>Shown below is a screenshot of the BreadCrumbBar control:
+ * 
+ * <br>
+ * <center>
+ * <img src="breadCrumbBar.png" alt="Screenshot of BreadCrumbBar">
+ * </center>
+ */
+public class BreadCrumbBar<T> extends ControlsFXControl {
+
+    private final EventHandlerManager eventHandlerManager = new EventHandlerManager(this);
+
+
+    /**
+     * Represents an Event which is fired when a bread crumb was activated.
+     */
+    @SuppressWarnings("serial")
+    public static class BreadCrumbActionEvent<TE> extends Event {
+        
+        /**
+         * The event type that should be listened to by people interested in 
+         * knowing when the {@link BreadCrumbBar#selectedCrumbProperty() selected crumb}
+         * has changed.
+         */
+        @SuppressWarnings("rawtypes")
+        public static final EventType<BreadCrumbActionEvent> CRUMB_ACTION = new EventType<>("CRUMB_ACTION"); //$NON-NLS-1$
+
+        private final TreeItem<TE> selectedCrumb;
+
+        /**
+         * Creates a new event that can subsequently be fired.
+         */
+        public BreadCrumbActionEvent(TreeItem<TE> selectedCrumb) {
+            super(CRUMB_ACTION);
+            this.selectedCrumb = selectedCrumb;
+        }
+
+        /**
+         * Returns the crumb which was the action target.
+         */
+        public TreeItem<TE> getSelectedCrumb() {
+            return selectedCrumb;
+        }
+    }
+    
+    
+    
+    /**
+     * Construct a tree model from the flat list which then can be set 
+     * as selectedCrumb node to be shown 
+     * @param crumbs
+     */
+    public static <T> TreeItem<T> buildTreeModel(@SuppressWarnings("unchecked") T... crumbs){
+        TreeItem<T> subRoot = null;
+        for (T crumb : crumbs) {
+            TreeItem<T> currentNode = new TreeItem<>(crumb);
+            if(subRoot == null){
+                subRoot = currentNode; 
+            }else{
+                subRoot.getChildren().add(currentNode);
+                subRoot = currentNode;
+            }
+        }
+        return subRoot;
+    }
+
+
+    
+    
+    
+    
+    /***************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+
+
+    /**
+     * Default crumb node factory. This factory is used when no custom factory is specified by the user.
+     */
+    private final Callback<TreeItem<T>, Button> defaultCrumbNodeFactory = new Callback<TreeItem<T>, Button>(){
+        @Override
+        public Button call(TreeItem<T> crumb) {
+            return new BreadCrumbBarSkin.BreadCrumbButton(crumb.getValue() != null ? crumb.getValue().toString() : ""); //$NON-NLS-1$
+        }
+    };
+    
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Creates an empty bread crumb bar
+     */
+    public BreadCrumbBar(){
+        this(null);
+    }
+
+    /**
+     * Creates a bread crumb bar with the given TreeItem as the currently 
+     * selected crumb.
+     */
+    public BreadCrumbBar(TreeItem<T> selectedCrumb) {
+        getStyleClass().add(DEFAULT_STYLE_CLASS);
+        setSelectedCrumb(selectedCrumb);
+        setCrumbFactory(defaultCrumbNodeFactory);
+    }
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /** {@inheritDoc} */
+    @Override public EventDispatchChain buildEventDispatchChain(EventDispatchChain tail) {
+        return tail.prepend(eventHandlerManager);
+    }
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Properties                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    // --- selectedCrumb
+    /**
+     * Represents the bottom-most path node (the node on the most-right side in 
+     * terms of the bread crumb bar). The full path is then being constructed 
+     * using getParent() of the tree-items.
+     * 
+     * <p>
+     * Consider the following hierarchy:
+     * [Root] &gt; [Folder] &gt; [SubFolder] &gt; [myfile.txt]
+     * 
+     * To show the above bread crumb bar, you have to set the [myfile.txt] tree-node as selected crumb.
+     */
+    public final ObjectProperty<TreeItem<T>> selectedCrumbProperty() {
+        return selectedCrumb;
+    }
+    private final ObjectProperty<TreeItem<T>> selectedCrumb = 
+            new SimpleObjectProperty<>(this, "selectedCrumb"); //$NON-NLS-1$
+    
+    /**
+     * Get the current target path
+     */
+    public final TreeItem<T> getSelectedCrumb() {
+        return selectedCrumb.get();
+    }
+
+    /**
+     * Select one node in the BreadCrumbBar for being the bottom-most path node.
+     * @param selectedCrumb 
+     */
+    public final void setSelectedCrumb(TreeItem<T> selectedCrumb){
+        this.selectedCrumb.set(selectedCrumb);
+    }
+
+    
+    // --- autoNavigation
+    /**
+     * Enable or disable auto navigation (default is enabled).
+     * If auto navigation is enabled, it will automatically navigate to the crumb which was clicked by the user.
+     * @return a {@link BooleanProperty}
+     */
+    public final BooleanProperty autoNavigationEnabledProperty() {
+        return autoNavigation;
+    }
+    
+    private final BooleanProperty autoNavigation = 
+            new SimpleBooleanProperty(this, "autoNavigationEnabled", true); //$NON-NLS-1$
+    
+    /**
+     * Return whether auto-navigation is enabled.
+     * @return whether auto-navigation is enabled.
+     */
+    public final boolean isAutoNavigationEnabled() {
+        return autoNavigation.get();
+    }
+    
+    /**
+     * Enable or disable auto navigation (default is enabled).
+     * If auto navigation is enabled, it will automatically navigate to the crumb which was clicked by the user.
+     * @param enabled 
+     */
+    public final void setAutoNavigationEnabled(boolean enabled) {
+        autoNavigation.set(enabled);
+    }
+
+
+    
+    // --- crumbFactory
+    /**
+     * Return an ObjectProperty of the CrumbFactory.
+     * @return an ObjectProperty of the CrumbFactory.
+     */
+    public final ObjectProperty<Callback<TreeItem<T>, Button>> crumbFactoryProperty() {
+        return crumbFactory;
+    }
+    
+    private final ObjectProperty<Callback<TreeItem<T>, Button>> crumbFactory = 
+            new SimpleObjectProperty<>(this, "crumbFactory"); //$NON-NLS-1$
+
+    /**
+     * Sets the crumb factory to create (custom) {@link BreadCrumbButton} instances.
+     * <code>null</code> is not allowed and will result in a fall back to the default factory.
+     * @param value 
+     */
+    public final void setCrumbFactory(Callback<TreeItem<T>, Button> value) {
+        if(value == null){
+            value = defaultCrumbNodeFactory;
+        }
+        crumbFactoryProperty().set(value);
+    }
+
+    /**
+     * Returns the cell factory that will be used to create {@link BreadCrumbButton} 
+     * instances
+     */
+    public final Callback<TreeItem<T>, Button> getCrumbFactory() {
+        return crumbFactory.get();
+    }
+
+    
+    // --- onCrumbAction
+    /**
+     * @return an ObjectProperty representing the crumbAction EventHandler being used.
+     */
+    public final ObjectProperty<EventHandler<BreadCrumbActionEvent<T>>> onCrumbActionProperty() { 
+        return onCrumbAction; 
+    }
+    
+    /**
+     * Set a new EventHandler for when a user selects a crumb.
+     * @param value 
+     */
+    public final void setOnCrumbAction(EventHandler<BreadCrumbActionEvent<T>> value) {
+        onCrumbActionProperty().set(value); 
+    }
+    
+    /**
+     * Return the EventHandler currently used when a user selects a crumb.
+     * @return the EventHandler currently used when a user selects a crumb.
+     */
+    public final EventHandler<BreadCrumbActionEvent<T>> getOnCrumbAction() { 
+        return onCrumbActionProperty().get(); 
+    }
+    
+    private ObjectProperty<EventHandler<BreadCrumbActionEvent<T>>> onCrumbAction = new ObjectPropertyBase<EventHandler<BreadCrumbBar.BreadCrumbActionEvent<T>>>() {
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        @Override protected void invalidated() {
+            eventHandlerManager.setEventHandler(BreadCrumbActionEvent.CRUMB_ACTION, (EventHandler<BreadCrumbActionEvent>)(Object)get());
+        }
+
+        @Override
+        public Object getBean() {
+            return BreadCrumbBar.this;
+        }
+
+        @Override
+        public String getName() {
+            return "onCrumbAction"; //$NON-NLS-1$
+        }
+    };
+    
+
+    /***************************************************************************
+     *                                                                         *
+     * Stylesheet Handling                                                     *
+     *                                                                         *
+     **************************************************************************/
+
+    private static final String DEFAULT_STYLE_CLASS = "bread-crumb-bar"; //$NON-NLS-1$
+
+    /** {@inheritDoc} */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new BreadCrumbBarSkin<>(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(BreadCrumbBar.class, "breadcrumbbar.css");
+    }
+}
diff --git a/src/org/controlsfx/control/CheckBitSetModelBase.java b/src/org/controlsfx/control/CheckBitSetModelBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ba976f2f469d10e6b27ee35c71ac179a208bcd8
--- /dev/null
+++ b/src/org/controlsfx/control/CheckBitSetModelBase.java
@@ -0,0 +1,315 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import java.util.BitSet;
+import java.util.Map;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+
+import com.sun.javafx.collections.MappingChange;
+import com.sun.javafx.collections.NonIterableChange;
+import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList;
+
+// not public API
+abstract class CheckBitSetModelBase<T> implements IndexedCheckModel<T> { 
+    
+    /***********************************************************************
+     *                                                                     *
+     * Internal properties                                                 *
+     *                                                                     *
+     **********************************************************************/
+
+    private final Map<T, BooleanProperty> itemBooleanMap;
+    
+    private final BitSet checkedIndices;
+    private final ReadOnlyUnbackedObservableList<Integer> checkedIndicesList;
+    private final ReadOnlyUnbackedObservableList<T> checkedItemsList;
+    
+    
+
+    /***********************************************************************
+     *                                                                     *
+     * Constructors                                                        *
+     *                                                                     *
+     **********************************************************************/
+
+    CheckBitSetModelBase(final Map<T, BooleanProperty> itemBooleanMap) {
+        this.itemBooleanMap = itemBooleanMap;
+        
+        this.checkedIndices = new BitSet();
+        
+        this.checkedIndicesList = new ReadOnlyUnbackedObservableList<Integer>() {
+            @Override public Integer get(int index) {
+                if (index < 0 || index >= getItemCount()) return -1;
+
+                for (int pos = 0, val = checkedIndices.nextSetBit(0);
+                    val >= 0 || pos == index;
+                    pos++, val = checkedIndices.nextSetBit(val+1)) {
+                        if (pos == index) return val;
+                }
+
+                return -1;
+            }
+
+            @Override public int size() {
+                return checkedIndices.cardinality();
+            }
+
+            @Override public boolean contains(Object o) {
+                if (o instanceof Number) {
+                    Number n = (Number) o;
+                    int index = n.intValue();
+
+                    return index >= 0 && index < checkedIndices.length() &&
+                            checkedIndices.get(index);
+                }
+
+                return false;
+            }
+        };
+        
+        this.checkedItemsList = new ReadOnlyUnbackedObservableList<T>() {
+            @Override public T get(int i) {
+                int pos = checkedIndicesList.get(i);
+                if (pos < 0 || pos >= getItemCount()) return null;
+                return getItem(pos);
+            }
+
+            @Override public int size() {
+                return checkedIndices.cardinality();
+            }
+        };
+        
+        final MappingChange.Map<Integer,T> map = f -> getItem(f);
+        
+        checkedIndicesList.addListener(new ListChangeListener<Integer>() {
+            @Override public void onChanged(final Change<? extends Integer> c) {
+                // when the selectedIndices ObservableList changes, we manually call
+                // the observers of the selectedItems ObservableList.
+                boolean hasRealChangeOccurred = false;
+                while (c.next() && ! hasRealChangeOccurred) {
+                    hasRealChangeOccurred = c.wasAdded() || c.wasRemoved();
+                }
+
+                if (hasRealChangeOccurred) {
+                    c.reset();
+                    checkedItemsList.callObservers(new MappingChange<>(c, map, checkedItemsList));
+                }
+                c.reset();
+            }
+        });
+        
+        // this code is to handle the situation where a developer is manually
+        // toggling the check model, and expecting the UI to update (without
+        // this it won't happen!).
+        getCheckedItems().addListener(new ListChangeListener<T>() {
+            @Override public void onChanged(ListChangeListener.Change<? extends T> c) {
+                while (c.next()) {
+                    if (c.wasAdded()) {
+                        for (T item : c.getAddedSubList()) {
+                            BooleanProperty p = getItemBooleanProperty(item);
+                            if (p != null) {
+                                p.set(true);
+                            }
+                        }
+                    } 
+                    
+                    if (c.wasRemoved()) {
+                        for (T item : c.getRemoved()) {
+                            BooleanProperty p = getItemBooleanProperty(item);
+                            if (p != null) {
+                                p.set(false);
+                            }
+                        }
+                    }
+                }
+            }
+        });
+    }
+    
+    
+    
+    /***********************************************************************
+     *                                                                     *
+     * Abstract API                                                        *
+     *                                                                     *
+     **********************************************************************/
+
+    @Override
+    public abstract T getItem(int index);
+    
+    @Override
+    public abstract int getItemCount();
+    
+    @Override
+    public abstract int getItemIndex(T item);
+    
+    BooleanProperty getItemBooleanProperty(T item) {
+        return itemBooleanMap.get(item);
+    }
+    
+    
+    /***********************************************************************
+     *                                                                     *
+     * Public selection API                                                *
+     *                                                                     *
+     **********************************************************************/
+    
+    /**
+     * Returns a read-only list of the currently checked indices in the CheckBox.
+     */
+    @Override
+    public ObservableList<Integer> getCheckedIndices() {
+        return checkedIndicesList;
+    }
+    
+    /**
+     * Returns a read-only list of the currently checked items in the CheckBox.
+     */
+    @Override
+    public ObservableList<T> getCheckedItems() {
+        return checkedItemsList;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void checkAll() {
+        for (int i = 0; i < getItemCount(); i++) {
+            check(i);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void checkIndices(int... indices) {
+        for (int i = 0; i < indices.length; i++) {
+            check(indices[i]);
+        }
+    }
+    
+    /** {@inheritDoc} */
+    @Override public void clearCheck(T item) {
+        int index = getItemIndex(item);
+        clearCheck(index);        
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void clearChecks() {
+        for( int index = 0; index < checkedIndices.length(); index++) {
+            clearCheck(index);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void clearCheck(int index) {
+        if (index < 0 || index >= getItemCount()) return;
+        checkedIndices.clear(index);
+        
+        final int changeIndex = checkedIndicesList.indexOf(index);
+        checkedIndicesList.callObservers(new NonIterableChange.SimpleRemovedChange<>(changeIndex, changeIndex, index, checkedIndicesList));
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public boolean isEmpty() {
+        return checkedIndices.isEmpty();
+    }
+    
+    /** {@inheritDoc} */
+    @Override public boolean isChecked(T item) {
+        int index = getItemIndex(item);
+        return isChecked(index);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isChecked(int index) {
+        return checkedIndices.get(index);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void check(int index) {
+        if (index < 0 || index >= getItemCount()) return;
+        checkedIndices.set(index);
+        final int changeIndex = checkedIndicesList.indexOf(index);
+        checkedIndicesList.callObservers(new NonIterableChange.SimpleAddChange<>(changeIndex, changeIndex+1, checkedIndicesList));
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void check(T item) {
+        int index = getItemIndex(item);
+        check(index);
+    }
+
+    
+    
+    
+    /***********************************************************************
+     *                                                                     *
+     * Private implementation                                              *
+     *                                                                     *
+     **********************************************************************/
+    
+    protected void updateMap() {
+        // reset the map
+        itemBooleanMap.clear();
+        for (int i = 0; i < getItemCount(); i++) {
+            final int index = i;
+            final T item = getItem(index);
+            
+            final BooleanProperty booleanProperty = new SimpleBooleanProperty(item, "selected", false); //$NON-NLS-1$
+            itemBooleanMap.put(item, booleanProperty);
+            
+            // this is where we listen to changes to the boolean properties,
+            // updating the selected indices list (and therefore indirectly
+            // the selected items list) when the checkbox is toggled
+            booleanProperty.addListener(new InvalidationListener() {
+                @Override public void invalidated(Observable o) {
+                    if (booleanProperty.get()) {
+                        checkedIndices.set(index);
+                        final int changeIndex = checkedIndicesList.indexOf(index);
+                        checkedIndicesList.callObservers(new NonIterableChange.SimpleAddChange<>(changeIndex, changeIndex+1, checkedIndicesList));                            
+                    } else {
+                        final int changeIndex = checkedIndicesList.indexOf(index);
+                        checkedIndices.clear(index);
+                        checkedIndicesList.callObservers(new NonIterableChange.SimpleRemovedChange<>(changeIndex, changeIndex, index, checkedIndicesList));
+                    }
+                }
+            });
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/CheckComboBox.java b/src/org/controlsfx/control/CheckComboBox.java
new file mode 100644
index 0000000000000000000000000000000000000000..86f175e63bc87f17a95f16ad237091054621eb29
--- /dev/null
+++ b/src/org/controlsfx/control/CheckComboBox.java
@@ -0,0 +1,297 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.CheckComboBoxSkin;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Skin;
+import javafx.util.StringConverter;
+
+/**
+ * A simple UI control that makes it possible to select zero or more items within
+ * a ComboBox-like control. Each row item shows a {@link CheckBox}, and the state
+ * of each row can be queried via the {@link #checkModelProperty() check model}.
+ * 
+ * <h3>Screenshot</h3>
+ * <p>The following screenshot shows the CheckComboBox with some sample data:
+ * 
+ * <br>
+ * <img src="checkComboBox.png" alt="Screenshot of CheckComboBox">
+ * 
+ * <h3>Code Example:</h3>
+ * <p>To create the CheckComboBox shown in the screenshot, simply do the 
+ * following:
+ * 
+ * <pre>
+ * {@code
+ * // create the data to show in the CheckComboBox 
+ * final ObservableList<String> strings = FXCollections.observableArrayList();
+ * for (int i = 0; i <= 100; i++) {
+ *     strings.add("Item " + i);
+ * }
+ * 
+ * // Create the CheckComboBox with the data 
+ * final CheckComboBox<String> checkComboBox = new CheckComboBox<String>(strings);
+ * 
+ * // and listen to the relevant events (e.g. when the selected indices or 
+ * // selected items change).
+ * checkComboBox.getCheckModel().getSelectedItems().addListener(new ListChangeListener<String>() {
+ *     public void onChanged(ListChangeListener.Change<? extends String> c) {
+ *         System.out.println(checkComboBox.getCheckModel().getSelectedItems());
+ *     }
+ * });}
+ * }</pre>
+ *
+ * @param <T> The type of the data in the ComboBox.
+ */
+public class CheckComboBox<T> extends ControlsFXControl {
+    
+    /**************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+    private final ObservableList<T> items;
+    private final Map<T, BooleanProperty> itemBooleanMap;
+    
+
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Creates a new CheckComboBox instance with an empty list of choices.
+     */
+    public CheckComboBox() {
+        this(null);
+    }
+    
+    /**
+     * Creates a new CheckComboBox instance with the given items available as
+     * choices.
+     * 
+     * @param items The items to display within the CheckComboBox.
+     */
+    public CheckComboBox(final ObservableList<T> items) {
+        final int initialSize = items == null ? 32 : items.size();
+        
+        this.itemBooleanMap = new HashMap<>(initialSize);
+        this.items = items == null ? FXCollections.<T>observableArrayList() : items;
+        setCheckModel(new CheckComboBoxBitSetCheckModel<>(this.items, itemBooleanMap));
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    /** {@inheritDoc} */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new CheckComboBoxSkin<>(this);
+    }
+    
+    /**
+     * Represents the list of choices available to the user, from which they can
+     * select zero or more items.
+     */
+    public ObservableList<T> getItems() {
+        return items;
+    }
+    
+    /**
+     * Returns the {@link BooleanProperty} for a given item index in the 
+     * CheckComboBox. This is useful if you want to bind to the property.
+     */
+    public BooleanProperty getItemBooleanProperty(int index) {
+        if (index < 0 || index >= items.size()) return null;
+        return getItemBooleanProperty(getItems().get(index));
+    }
+    
+    /**
+     * Returns the {@link BooleanProperty} for a given item in the 
+     * CheckComboBox. This is useful if you want to bind to the property.
+     */
+    public BooleanProperty getItemBooleanProperty(T item) {
+        return itemBooleanMap.get(item);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+
+    // --- Check Model
+    private ObjectProperty<IndexedCheckModel<T>> checkModel = 
+            new SimpleObjectProperty<>(this, "checkModel"); //$NON-NLS-1$
+    
+    /**
+     * Sets the 'check model' to be used in the CheckComboBox - this is the
+     * code that is responsible for representing the selected state of each
+     * {@link CheckBox} - that is, whether each {@link CheckBox} is checked or 
+     * not (and not to be confused with the 
+     * selection model concept, which is used in the ComboBox control to 
+     * represent the selection state of each row).. 
+     */
+    public final void setCheckModel(IndexedCheckModel<T> value) {
+        checkModelProperty().set(value);
+    }
+
+    /**
+     * Returns the currently installed check model.
+     */
+    public final IndexedCheckModel<T> getCheckModel() {
+        return checkModel == null ? null : checkModel.get();
+    }
+
+    /**
+     * The check model provides the API through which it is possible
+     * to check single or multiple items within a CheckComboBox, as  well as inspect
+     * which items have been checked by the user. Note that it has a generic
+     * type that must match the type of the CheckComboBox itself.
+     */
+    public final ObjectProperty<IndexedCheckModel<T>> checkModelProperty() {
+        return checkModel;
+    }
+    
+    // --- converter
+    private ObjectProperty<StringConverter<T>> converter = 
+            new SimpleObjectProperty<StringConverter<T>>(this, "converter");
+    
+    /**
+     * A {@link StringConverter} that, given an object of type T, will 
+     * return a String that can be used to represent the object visually.
+     */
+    public final ObjectProperty<StringConverter<T>> converterProperty() { 
+        return converter; 
+    }
+    
+    /** 
+     * Sets the {@link StringConverter} to be used in the control.
+     * @param value A {@link StringConverter} that, given an object of type T, will 
+     * return a String that can be used to represent the object visually.
+     */
+    public final void setConverter(StringConverter<T> value) { 
+        converterProperty().set(value); 
+    }
+    
+    /**
+     * A {@link StringConverter} that, given an object of type T, will 
+     * return a String that can be used to represent the object visually.
+     */
+    public final StringConverter<T> getConverter() { 
+        return converterProperty().get(); 
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Implementation
+     * 
+     **************************************************************************/
+    
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Support classes
+     * 
+     **************************************************************************/
+    
+    private static class CheckComboBoxBitSetCheckModel<T> extends CheckBitSetModelBase<T> {
+        
+        /***********************************************************************
+         *                                                                     *
+         * Internal properties                                                 *
+         *                                                                     *
+         **********************************************************************/
+        
+        private final ObservableList<T> items;
+        
+        
+        
+        /***********************************************************************
+         *                                                                     *
+         * Constructors                                                        *
+         *                                                                     *
+         **********************************************************************/
+        
+        CheckComboBoxBitSetCheckModel(final ObservableList<T> items, final Map<T, BooleanProperty> itemBooleanMap) {
+            super(itemBooleanMap);
+            
+            this.items = items;
+            this.items.addListener(new ListChangeListener<T>() {
+                @Override public void onChanged(Change<? extends T> c) {
+                    updateMap();
+                }
+            });
+            
+            updateMap();
+        }
+        
+        
+        
+        /***********************************************************************
+         *                                                                     *
+         * Implementing abstract API                                           *
+         *                                                                     *
+         **********************************************************************/
+
+        @Override public T getItem(int index) {
+            return items.get(index);
+        }
+        
+        @Override public int getItemCount() {
+            return items.size();
+        }
+        
+        @Override public int getItemIndex(T item) {
+            return items.indexOf(item);
+        }
+    }
+}
diff --git a/src/org/controlsfx/control/CheckListView.java b/src/org/controlsfx/control/CheckListView.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ec23b02c3e5fb816989b110d458826aef0409d5
--- /dev/null
+++ b/src/org/controlsfx/control/CheckListView.java
@@ -0,0 +1,264 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ListView;
+import javafx.scene.control.cell.CheckBoxListCell;
+import javafx.util.Callback;
+
+/**
+ * A simple UI control that makes it possible to select zero or more items within
+ * a ListView without the need to set a custom cell factory or manually create
+ * boolean properties for each row - simply use the 
+ * {@link #checkModelProperty() check model} to request the current selection 
+ * state.
+ * 
+ * <h3>Screenshot</h3>
+ * <p>The following screenshot shows the CheckListView with some sample data:
+ * 
+ * <br>
+ * <img src="checkListView.png" alt="Screenshot of CheckListView">
+ * 
+ * <h3>Code Example:</h3>
+ * <p>To create the CheckListView shown in the screenshot, simply do the 
+ * following:
+ * 
+ * <pre>
+ * {@code
+ * // create the data to show in the CheckListView 
+ * final ObservableList<String> strings = FXCollections.observableArrayList();
+ * for (int i = 0; i <= 100; i++) {
+ *     strings.add("Item " + i);
+ * }
+ * 
+ * // Create the CheckListView with the data 
+ * final CheckListView<String> checkListView = new CheckListView<>(strings);
+ *       
+ * // and listen to the relevant events (e.g. when the selected indices or 
+ * // selected items change).
+ * checkListView.getCheckModel().getCheckedItems().addListener(new ListChangeListener<String>() {
+ *     public void onChanged(ListChangeListener.Change<? extends String> c) {
+ *         System.out.println(checkListView.getCheckModel().getCheckedItems());
+ *     }
+ * });
+ * }</pre>
+ *
+ * @param <T> The type of the data in the CheckListView.
+ */
+public class CheckListView<T> extends ListView<T> {
+    
+    /**************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+    private final Map<T, BooleanProperty> itemBooleanMap;
+    
+
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Creates a new CheckListView instance with an empty list of choices.
+     */
+    public CheckListView() {
+        this(FXCollections.<T> observableArrayList());
+    }
+    
+    /**
+     * Creates a new CheckListView instance with the given items available as
+     * choices.
+     * 
+     * @param items The items to display within the CheckListView.
+     */
+    public CheckListView(ObservableList<T> items) {
+        super(items);
+        this.itemBooleanMap = new HashMap<>();
+        
+        setCheckModel(new CheckListViewBitSetCheckModel<>(getItems(), itemBooleanMap));
+        itemsProperty().addListener(ov -> {
+            setCheckModel(new CheckListViewBitSetCheckModel<>(getItems(), itemBooleanMap));
+        });
+        
+        setCellFactory(listView -> new CheckBoxListCell<>(new Callback<T, ObservableValue<Boolean>>() {
+            @Override public ObservableValue<Boolean> call(T item) {
+                return getItemBooleanProperty(item);
+            }
+        }));
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    /**
+     * Returns the {@link BooleanProperty} for a given item index in the 
+     * CheckListView. This is useful if you want to bind to the property.
+     */
+    public BooleanProperty getItemBooleanProperty(int index) {
+        if (index < 0 || index >= getItems().size()) return null;
+        return getItemBooleanProperty(getItems().get(index));
+    }
+    
+    /**
+     * Returns the {@link BooleanProperty} for a given item in the 
+     * CheckListView. This is useful if you want to bind to the property.
+     */
+    public BooleanProperty getItemBooleanProperty(T item) {
+        return itemBooleanMap.get(item);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+
+    // --- Check Model
+    private ObjectProperty<IndexedCheckModel<T>> checkModel = 
+            new SimpleObjectProperty<>(this, "checkModel"); //$NON-NLS-1$
+    
+    /**
+     * Sets the 'check model' to be used in the CheckListView - this is the
+     * code that is responsible for representing the selected state of each
+     * {@link CheckBox} - that is, whether each {@link CheckBox} is checked or 
+     * not (and not to be confused with the 
+     * selection model concept, which is used in the ListView control to 
+     * represent the selection state of each row).. 
+     */
+    public final void setCheckModel(IndexedCheckModel<T> value) {
+        checkModelProperty().set(value);
+    }
+
+    /**
+     * Returns the currently installed check model.
+     */
+    public final IndexedCheckModel<T> getCheckModel() {
+        return checkModel == null ? null : checkModel.get();
+    }
+
+    /**
+     * The check model provides the API through which it is possible
+     * to check single or multiple items within a CheckListView, as  well as inspect
+     * which items have been checked by the user. Note that it has a generic
+     * type that must match the type of the CheckListView itself.
+     */
+    public final ObjectProperty<IndexedCheckModel<T>> checkModelProperty() {
+        return checkModel;
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Implementation
+     * 
+     **************************************************************************/
+    
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Support classes
+     * 
+     **************************************************************************/
+    
+    private static class CheckListViewBitSetCheckModel<T> extends CheckBitSetModelBase<T> {
+        
+        /***********************************************************************
+         *                                                                     *
+         * Internal properties                                                 *
+         *                                                                     *
+         **********************************************************************/
+        
+        private final ObservableList<T> items;
+        
+        
+        
+        /***********************************************************************
+         *                                                                     *
+         * Constructors                                                        *
+         *                                                                     *
+         **********************************************************************/
+        
+        CheckListViewBitSetCheckModel(final ObservableList<T> items, final Map<T, BooleanProperty> itemBooleanMap) {
+            super(itemBooleanMap);
+            
+            this.items = items;
+            this.items.addListener(new ListChangeListener<T>() {
+                @Override public void onChanged(Change<? extends T> c) {
+                    updateMap();
+                }
+            });
+            
+            updateMap();
+        }
+        
+        
+        
+        /***********************************************************************
+         *                                                                     *
+         * Implementing abstract API                                           *
+         *                                                                     *
+         **********************************************************************/
+
+        @Override public T getItem(int index) {
+            return items.get(index);
+        }
+        
+        @Override public int getItemCount() {
+            return items.size();
+        }
+        
+        @Override public int getItemIndex(T item) {
+            return items.indexOf(item);
+        }
+    }
+}
diff --git a/src/org/controlsfx/control/CheckModel.java b/src/org/controlsfx/control/CheckModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..c305ae2a4fd5bf6b8705c6081d957e33eed5416c
--- /dev/null
+++ b/src/org/controlsfx/control/CheckModel.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import javafx.collections.ObservableList;
+
+public interface CheckModel<T> {
+    
+    /**
+     * Returns the count of items in the control.
+     */
+    public int getItemCount();
+
+    /**
+     * Returns a read-only list of the currently checked items in the control.
+     */
+    public ObservableList<T> getCheckedItems();
+
+    /**
+     * Checks all items in the control
+     */
+    public void checkAll();
+    
+    public void clearCheck(T item);
+    
+    /**
+     * Unchecks all items in the control
+     */
+    public void clearChecks();
+    
+    /**
+     * Returns true if there are no checked items in the control.
+     */
+    public boolean isEmpty();
+    
+    public boolean isChecked(T item);
+    
+    /**
+     * Checks the given item in the control.
+     */
+    public void check(T item);
+}
diff --git a/src/org/controlsfx/control/CheckTreeView.java b/src/org/controlsfx/control/CheckTreeView.java
new file mode 100644
index 0000000000000000000000000000000000000000..d8b8689a7aa7511e11d471060f1fb87e6538527f
--- /dev/null
+++ b/src/org/controlsfx/control/CheckTreeView.java
@@ -0,0 +1,327 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.CheckBoxTreeItem;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.scene.control.cell.CheckBoxTreeCell;
+
+/**
+ * A simple UI control that makes it possible to select zero or more items within
+ * a TreeView without the need to set a custom cell factory or manually create
+ * boolean properties for each row - simply use the 
+ * {@link #checkModelProperty() check model} to request the current selection 
+ * state.
+ * 
+ * <h3>Screenshot</h3>
+ * <p>The following screenshot shows the CheckTreeView with some sample data:
+ * 
+ * <br>
+ * <img src="checkTreeView.png" alt="Screenshot of CheckTreeView">
+ * 
+ * <h3>Code Example:</h3>
+ * <p>To create the CheckTreeView shown in the screenshot, simply do the 
+ * following:
+ * 
+ * <pre>
+ * {@code
+ * // create the data to show in the CheckTreeView 
+ * CheckBoxTreeItem<String> root = new CheckBoxTreeItem<String>("Root");
+ * root.setExpanded(true);
+ * root.getChildren().addAll(
+ *               new CheckBoxTreeItem<String>("Jonathan"),
+ *               new CheckBoxTreeItem<String>("Eugene"),
+ *               new CheckBoxTreeItem<String>("Henri"),
+ *               new CheckBoxTreeItem<String>("Samir"));
+ * 
+ * // Create the CheckTreeView with the data 
+ * final CheckTreeView<String> checkTreeView = new CheckTreeView<>(root);
+ *       
+ * // and listen to the relevant events (e.g. when the checked items change).
+ * checkTreeView.getCheckModel().getCheckedItems().addListener(new ListChangeListener<TreeItem<String>>() {
+ *      public void onChanged(ListChangeListener.Change<? extends TreeItem<String>> c) {
+ *          System.out.println(checkTreeView.getCheckModel().getCheckedItems());
+ *      }
+ * });
+ * }</pre>
+ *
+ * @param <T> The type of the data in the TreeView.
+ */
+public class CheckTreeView<T> extends TreeView<T> {
+    
+    /**************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+    
+
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Creates a new CheckTreeView instance with an empty tree of choices.
+     */
+    public CheckTreeView() {
+        this(null);
+    }
+    
+    /**
+     * Creates a new CheckTreeView instance with the given CheckBoxTreeItem set
+     * as the tree root.
+     * 
+     * @param root The root tree item to display in the CheckTreeView.
+     */
+    public CheckTreeView(final CheckBoxTreeItem<T> root) {
+        super(root);
+        rootProperty().addListener(o -> updateCheckModel());
+
+        updateCheckModel();
+
+        setCellFactory(CheckBoxTreeCell.<T> forTreeView());
+    }
+    
+    protected void updateCheckModel() {
+        if (getRoot() != null) {        
+            setCheckModel(new CheckTreeViewCheckModel<>(this));
+        }
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    /**
+     * Returns the {@link BooleanProperty} for a given item index in the 
+     * CheckTreeView. This is useful if you want to bind to the property.
+     */
+    public BooleanProperty getItemBooleanProperty(int index) {
+        CheckBoxTreeItem<T> treeItem = (CheckBoxTreeItem<T>) getTreeItem(index);
+        return treeItem.selectedProperty();
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+
+    // --- Check Model
+    private ObjectProperty<CheckModel<TreeItem<T>>> checkModel = 
+            new SimpleObjectProperty<>(this, "checkModel"); //$NON-NLS-1$
+    
+    /**
+     * Sets the 'check model' to be used in the CheckTreeView - this is the
+     * code that is responsible for representing the selected state of each
+     * {@link CheckBox} - that is, whether each {@link CheckBox} is checked or 
+     * not (and not to be confused with the 
+     * selection model concept, which is used in the TreeView control to 
+     * represent the selection state of each row).. 
+     */
+    public final void setCheckModel(CheckModel<TreeItem<T>> value) {
+        checkModelProperty().set(value);
+    }
+
+    /**
+     * Returns the currently installed check model.
+     */
+    public final CheckModel<TreeItem<T>> getCheckModel() {
+        return checkModel == null ? null : checkModel.get();
+    }
+
+    /**
+     * The check model provides the API through which it is possible
+     * to check single or multiple items within a CheckTreeView, as  well as inspect
+     * which items have been checked by the user. Note that it has a generic
+     * type that must match the type of the CheckTreeView itself.
+     */
+    public final ObjectProperty<CheckModel<TreeItem<T>>> checkModelProperty() {
+        return checkModel;
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Implementation
+     * 
+     **************************************************************************/
+    
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Support classes
+     * 
+     **************************************************************************/
+    
+    private static class CheckTreeViewCheckModel<T> implements CheckModel<TreeItem<T>> {// extends CheckBitSetModelBase<TreeItem<T>> {
+        
+        /***********************************************************************
+         *                                                                     *
+         * Internal properties                                                 *
+         *                                                                     *
+         **********************************************************************/
+        
+        private final CheckTreeView<T> treeView;
+        private final TreeItem<T> root;
+        
+        private ObservableList<TreeItem<T>> checkedItems = FXCollections.observableArrayList();
+        
+        
+        
+        /***********************************************************************
+         *                                                                     *
+         * Constructors                                                        *
+         *                                                                     *
+         **********************************************************************/
+        
+        CheckTreeViewCheckModel(final CheckTreeView<T> treeView) {
+            this.treeView = treeView;
+            this.root = treeView.getRoot();
+            this.root.addEventHandler(CheckBoxTreeItem.<T>checkBoxSelectionChangedEvent(), e -> {
+                CheckBoxTreeItem<T> treeItem = e.getTreeItem();
+                
+                if (treeItem.isSelected()) { // && ! treeItem.isIndeterminate()) {
+                    check(treeItem);
+                } else { 
+                    clearCheck(treeItem);
+                }
+            });
+            
+            // we should reset the check model and then update the checked items
+            // based on the currently checked items in the tree view
+            clearChecks();
+            for (int i = 0; i < treeView.getExpandedItemCount(); i++) {
+                CheckBoxTreeItem<T> treeItem = (CheckBoxTreeItem<T>) treeView.getTreeItem(i);
+                if (treeItem.isSelected() && ! treeItem.isIndeterminate()) {
+                    check(treeItem);
+                }
+            }
+        }
+        
+        
+        
+        /***********************************************************************
+         *                                                                     *
+         * Implementing abstract API                                           *
+         *                                                                     *
+         **********************************************************************/
+
+        @Override public int getItemCount() {
+            return treeView.getExpandedItemCount();
+        }
+
+
+        // TODO make read-only
+        @Override public ObservableList<TreeItem<T>> getCheckedItems() {
+            return checkedItems;
+        }
+
+        @Override public void checkAll() {
+            iterateOverTree(this::check);
+        }
+
+        @Override public void clearCheck(TreeItem<T> item) {
+            if (item instanceof CheckBoxTreeItem) {
+                ((CheckBoxTreeItem<T>)item).setSelected(false);
+            }
+            checkedItems.remove(item);
+        }
+
+        @Override public void clearChecks() {
+            List<TreeItem<T>> items = new ArrayList<>(checkedItems);
+            for(TreeItem<T> item : items){
+                clearCheck(item);
+            }
+        }
+
+        @Override public boolean isEmpty() {
+            return checkedItems.isEmpty();
+        }
+
+        @Override public boolean isChecked(TreeItem<T> item) {
+            return checkedItems.contains(item);
+        }
+
+        @Override public void check(TreeItem<T> item) {
+            if (item instanceof CheckBoxTreeItem) {
+                ((CheckBoxTreeItem<T>)item).setSelected(true);
+            }
+            if (!checkedItems.contains(item)) {
+                checkedItems.add(item);
+            }
+        }
+        
+        
+        
+        /***********************************************************************
+         *                                                                     *
+         * Private Implementation                                              *
+         *                                                                     *
+         **********************************************************************/
+        
+        private void iterateOverTree(Consumer<TreeItem<T>> consumer) {
+            processNode(consumer, root);
+        }
+        
+        private void processNode(Consumer<TreeItem<T>> consumer, TreeItem<T> node) {
+            if (node == null) return;
+            consumer.accept(node);
+            processChildren(consumer, node.getChildren());
+        }
+        
+        private void processChildren(Consumer<TreeItem<T>> consumer, List<TreeItem<T>> children) {
+            if (children == null) return;
+            for (TreeItem<T> child : children) {
+                processNode(consumer, child);
+            }
+        }
+    }
+}
diff --git a/src/org/controlsfx/control/ControlsFXControl.java b/src/org/controlsfx/control/ControlsFXControl.java
new file mode 100644
index 0000000000000000000000000000000000000000..15b3057358945566ab2b13f7b97caadef3ac3bc6
--- /dev/null
+++ b/src/org/controlsfx/control/ControlsFXControl.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.version.VersionChecker;
+import javafx.scene.control.Control;
+
+abstract class ControlsFXControl extends Control {
+
+    public ControlsFXControl() {
+        VersionChecker.doVersionCheck();
+    }
+
+    private String stylesheet;
+
+    /**
+     * A helper method that ensures that the resource based lookup of the user
+     * agent stylesheet only happens once. Caches the external form of the
+     * resource.
+     *
+     * @param clazz
+     *            the class used for the resource lookup
+     * @param fileName
+     *            the name of the user agent stylesheet
+     * @return the external form of the user agent stylesheet (the path)
+     */
+    protected final String getUserAgentStylesheet(Class<?> clazz,
+            String fileName) {
+
+        /*
+         * For more information please see RT-40658
+         */
+        if (stylesheet == null) {
+            stylesheet = clazz.getResource(fileName).toExternalForm();
+        }
+
+        return stylesheet;
+    }
+}
diff --git a/src/org/controlsfx/control/GridCell.java b/src/org/controlsfx/control/GridCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..158ec896ca396b822ec1cbfa192c5b35aae4fb5f
--- /dev/null
+++ b/src/org/controlsfx/control/GridCell.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.GridCellSkin;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.scene.control.IndexedCell;
+import javafx.scene.control.ListView;
+import javafx.scene.control.Skin;
+import javafx.scene.control.TableView;
+
+/**
+ * A GridCell is created to represent items in the {@link GridView} 
+ * {@link GridView#getItems() items list}. As with other JavaFX UI controls
+ * (like {@link ListView}, {@link TableView}, etc), the {@link GridView} control
+ * is virtualised, meaning it is exceedingly memory and CPU efficient. Refer to
+ * the {@link GridView} class documentation for more details.
+ *  
+ * @see GridView
+ */
+public class GridCell<T> extends IndexedCell<T> {
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+
+    /**
+     * Creates a default GridCell instance.
+     */
+	public GridCell() {
+		getStyleClass().add("grid-cell"); //$NON-NLS-1$
+		
+//		itemProperty().addListener(new ChangeListener<T>() {
+//            @Override public void changed(ObservableValue<? extends T> arg0, T oldItem, T newItem) {
+//                updateItem(newItem, newItem == null);
+//            }
+//        });
+		
+		// TODO listen for index change and update index and item, rather than
+		// listen to just item update as above. This requires the GridCell to 
+		// know about its containing GridRow (and the GridRow to know its 
+		// containing GridView)
+		indexProperty().addListener(new InvalidationListener() {
+            @Override public void invalidated(Observable observable) {
+                final GridView<T> gridView = getGridView();
+                if (gridView == null) return;
+                
+                if(getIndex() < 0) {
+                    updateItem(null, true);
+                    return;
+                }
+                T item = gridView.getItems().get(getIndex());
+                
+//                updateIndex(getIndex());
+                updateItem(item, item == null);
+            }
+        });
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override protected Skin<?> createDefaultSkin() {
+        return new GridCellSkin<>(this);
+    }
+	
+	
+	
+	/**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+	
+	/**
+     * The {@link GridView} that this GridCell exists within.
+     */
+    public SimpleObjectProperty<GridView<T>> gridViewProperty() {
+        return gridView;
+    }
+    private final SimpleObjectProperty<GridView<T>> gridView = 
+            new SimpleObjectProperty<>(this, "gridView"); //$NON-NLS-1$
+    
+    /**
+     * Sets the {@link GridView} that this GridCell exists within.
+     */
+    public final void updateGridView(GridView<T> gridView) {
+        this.gridView.set(gridView);
+    }
+    
+    /**
+     * Returns the {@link GridView} that this GridCell exists within.
+     */
+    public GridView<T> getGridView() {
+        return gridView.get();
+    }
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/GridView.java b/src/org/controlsfx/control/GridView.java
new file mode 100644
index 0000000000000000000000000000000000000000..c575fe36b09cc496ba6a6d4975e2d4ba87db5607
--- /dev/null
+++ b/src/org/controlsfx/control/GridView.java
@@ -0,0 +1,560 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.GridViewSkin;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.css.CssMetaData;
+import javafx.css.StyleConverter;
+import javafx.css.Styleable;
+import javafx.css.StyleableDoubleProperty;
+import javafx.css.StyleableProperty;
+import javafx.scene.Node;
+import javafx.scene.control.Cell;
+import javafx.scene.control.Control;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.Skin;
+import javafx.scene.paint.Color;
+import javafx.util.Callback;
+
+import org.controlsfx.control.cell.ColorGridCell;
+
+/**
+ * A GridView is a virtualised control for displaying {@link #getItems()} in a
+ * visual, scrollable, grid-like fashion. In other words, whereas a ListView 
+ * shows one {@link ListCell} per row, in a GridView there will be zero or more
+ * {@link GridCell} instances on a single row.
+ * 
+ * <p> This approach means that the number of GridCell instances
+ * instantiated will be a significantly smaller number than the number of 
+ * items in the GridView items list, as only enough GridCells are created for
+ * the visible area of the GridView. This helps to improve performance and 
+ * reduce memory consumption. 
+ * 
+ * <p>Because each {@link GridCell} extends from {@link Cell}, the same approach
+ * of cell factories that is taken in other UI controls is also taken in GridView.
+ * This has two main benefits: 
+ * 
+ * <ol>
+ *   <li>GridCells are created on demand and without user involvement,
+ *   <li>GridCells can be arbitrarily complex. A simple GridCell may just have 
+ *   its {@link GridCell#textProperty() text property} set, whereas a more complex
+ *   GridCell can have an arbitrarily complex scenegraph set inside its
+ *   {@link GridCell#graphicProperty() graphic property} (as it accepts any Node).
+ * </ol>
+ *
+ * <h3>Examples</h3>
+ * <p>The following screenshot shows the GridView with the {@link ColorGridCell}
+ * being used:
+ * 
+ * <br>
+ * <img src="gridView.png" alt="Screenshot of GridView">
+ * 
+ * <p>To create this GridView was simple. Note that the majority of the code below
+ * is related to randomly creating the colours to be represented:
+ * 
+ * <pre>
+ * {@code
+ * GridView<Color> myGrid = new GridView<>(list);
+ * myGrid.setCellFactory(new Callback<GridView<Color>, GridCell<Color>>() {
+ *     public GridCell<Color> call(GridView<Color> gridView) {
+ *         return new ColorGridCell();
+ *     }
+ * });
+ * Random r = new Random(System.currentTimeMillis());
+ * for(int i = 0; i < 500; i++) {
+ *     list.add(new Color(r.nextDouble(), r.nextDouble(), r.nextDouble(), 1.0));
+ * }
+ * }</pre>
+ * 
+ * @see GridCell
+ */
+public class GridView<T> extends ControlsFXControl {
+
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Creates a default, empty GridView control.
+     */
+    public GridView() {
+        this(FXCollections.<T> observableArrayList());
+    }
+    
+    /**
+     * Creates a default GridView control with the provided items prepopulated.
+     * 
+     * @param items The items to display inside the GridView.
+     */
+    public GridView(ObservableList<T> items) {
+        getStyleClass().add(DEFAULT_STYLE_CLASS);
+        setItems(items);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new GridViewSkin<>(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(GridView.class, "gridview.css");
+    }
+    
+    /**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+    
+    // --- horizontal cell spacing
+    /**
+     * Property for specifying how much spacing there is between each cell
+     * in a row (i.e. how much horizontal spacing there is).
+     */
+    public final DoubleProperty horizontalCellSpacingProperty() {
+        if (horizontalCellSpacing == null) {
+            horizontalCellSpacing = new StyleableDoubleProperty(12) {
+                @Override public CssMetaData<GridView<?>, Number> getCssMetaData() {
+                    return GridView.StyleableProperties.HORIZONTAL_CELL_SPACING;
+                }
+                
+                @Override public Object getBean() {
+                    return GridView.this;
+                }
+
+                @Override public String getName() {
+                    return "horizontalCellSpacing"; //$NON-NLS-1$
+                }
+            };
+        }
+        return horizontalCellSpacing;
+    }
+    private DoubleProperty horizontalCellSpacing;
+    
+    /**
+     * Sets the amount of horizontal spacing there should be between cells in
+     * the same row.
+     * @param value The amount of spacing to use.
+     */
+    public final void setHorizontalCellSpacing(double value) {
+        horizontalCellSpacingProperty().set(value);
+    }
+    
+    /**
+     * Returns the amount of horizontal spacing there is between cells in
+     * the same row.
+     */
+    public final double getHorizontalCellSpacing() {
+        return horizontalCellSpacing == null ? 12.0 : horizontalCellSpacing.get();
+    }
+
+
+    
+    // --- vertical cell spacing
+    /**
+     * Property for specifying how much spacing there is between each cell
+     * in a column (i.e. how much vertical spacing there is).
+     */
+    private DoubleProperty verticalCellSpacing;
+    public final DoubleProperty verticalCellSpacingProperty() {
+        if (verticalCellSpacing == null) {
+            verticalCellSpacing = new StyleableDoubleProperty(12) {
+                @Override public CssMetaData<GridView<?>, Number> getCssMetaData() {
+                    return GridView.StyleableProperties.VERTICAL_CELL_SPACING;
+                }
+                
+                @Override public Object getBean() {
+                    return GridView.this;
+                }
+
+                @Override public String getName() {
+                    return "verticalCellSpacing"; //$NON-NLS-1$
+                }
+            };
+        }
+        return verticalCellSpacing;
+    }
+    
+    /**
+     * Sets the amount of vertical spacing there should be between cells in
+     * the same column.
+     * @param value The amount of spacing to use.
+     */
+    public final void setVerticalCellSpacing(double value) {
+        verticalCellSpacingProperty().set(value);
+    }
+
+    /**
+     * Returns the amount of vertical spacing there is between cells in
+     * the same column.
+     */
+    public final double getVerticalCellSpacing() {
+        return verticalCellSpacing == null ? 12.0 : verticalCellSpacing.get();
+    }
+
+    
+    
+    // --- cell width
+    /**
+     * Property representing the width that all cells should be.
+     */
+    public final DoubleProperty cellWidthProperty() {
+        if (cellWidth == null) {
+            cellWidth = new StyleableDoubleProperty(64) {
+                @Override public CssMetaData<GridView<?>, Number> getCssMetaData() {
+                    return GridView.StyleableProperties.CELL_WIDTH;
+                }
+                
+                @Override public Object getBean() {
+                    return GridView.this;
+                }
+
+                @Override public String getName() {
+                    return "cellWidth"; //$NON-NLS-1$
+                }
+            };
+        }
+        return cellWidth;
+    }
+    private DoubleProperty cellWidth;
+
+    /**
+     * Sets the width that all cells should be.
+     */
+    public final void setCellWidth(double value) {
+        cellWidthProperty().set(value);
+    }
+
+    /**
+     * Returns the width that all cells should be.
+     */
+    public final double getCellWidth() {
+        return cellWidth == null ? 64.0 : cellWidth.get();
+    }
+
+    
+    // --- cell height
+    /**
+     * Property representing the height that all cells should be.
+     */
+    public final DoubleProperty cellHeightProperty() {
+        if (cellHeight == null) {
+            cellHeight = new StyleableDoubleProperty(64) {
+                @Override public CssMetaData<GridView<?>, Number> getCssMetaData() {
+                    return GridView.StyleableProperties.CELL_HEIGHT;
+                }
+                
+                @Override public Object getBean() {
+                    return GridView.this;
+                }
+
+                @Override public String getName() {
+                    return "cellHeight"; //$NON-NLS-1$
+                }
+            };
+        }
+        return cellHeight;
+    }
+    private DoubleProperty cellHeight;
+
+    /**
+     * Sets the height that all cells should be.
+     */
+    public final void setCellHeight(double value) {
+        cellHeightProperty().set(value);
+    }
+
+    /**
+     * Returns the height that all cells should be.
+     */
+    public final double getCellHeight() {
+        return cellHeight == null ? 64.0 : cellHeight.get();
+    }
+
+    
+    // I've removed this functionality until there is a clear need for it.
+    // To re-enable it, there is code in GridRowSkin that has been commented
+    // out that must be re-enabled.
+    // Don't forget also to enable the styleable property further down in this
+    // class.
+//    // --- horizontal alignment
+//    private ObjectProperty<HPos> horizontalAlignment;
+//    public final ObjectProperty<HPos> horizontalAlignmentProperty() {
+//        if (horizontalAlignment == null) {
+//            horizontalAlignment = new StyleableObjectProperty<HPos>(HPos.CENTER) {
+//                @Override public CssMetaData<GridView<?>,HPos> getCssMetaData() {
+//                    return GridView.StyleableProperties.HORIZONTAL_ALIGNMENT;
+//                }
+//                
+//                @Override public Object getBean() {
+//                    return GridView.this;
+//                }
+//
+//                @Override public String getName() {
+//                    return "horizontalAlignment";
+//                }
+//            };
+//        }
+//        return horizontalAlignment;
+//    }
+//
+//    public final void setHorizontalAlignment(HPos value) {
+//        horizontalAlignmentProperty().set(value);
+//    }
+//
+//    public final HPos getHorizontalAlignment() {
+//        return horizontalAlignment == null ? HPos.CENTER : horizontalAlignment.get();
+//    }
+
+    
+    // --- cell factory
+    /**
+     * Property representing the cell factory that is currently set in this
+     * GridView, or null if no cell factory has been set (in which case the 
+     * default cell factory provided by the GridView skin will be used). The cell
+     * factory is used for instantiating enough GridCell instances for the 
+     * visible area of the GridView. Refer to the GridView class documentation
+     * for more information and examples.
+     */
+    public final ObjectProperty<Callback<GridView<T>, GridCell<T>>> cellFactoryProperty() {
+        if (cellFactory == null) {
+            cellFactory = new SimpleObjectProperty<>(this, "cellFactory"); //$NON-NLS-1$
+        }
+        return cellFactory;
+    }
+    private ObjectProperty<Callback<GridView<T>, GridCell<T>>> cellFactory;
+
+    /**
+     * Sets the cell factory to use to create {@link GridCell} instances to 
+     * show in the GridView.
+     */
+    public final void setCellFactory(Callback<GridView<T>, GridCell<T>> value) {
+        cellFactoryProperty().set(value);
+    }
+
+    /**
+     * Returns the cell factory that will be used to create {@link GridCell} 
+     * instances to show in the GridView.
+     */
+    public final Callback<GridView<T>, GridCell<T>> getCellFactory() {
+        return cellFactory == null ? null : cellFactory.get();
+    }
+
+    
+    // --- items
+    /**
+     * The items to be displayed in the GridView (as rendered via {@link GridCell}
+     * instances). For example, if the {@link ColorGridCell} were being used
+     * (as in the case at the top of this class documentation), this items list
+     * would be populated with {@link Color} values. It is important to 
+     * appreciate that the items list is used for the data, not the rendering.
+     * What is meant by this is that the items list should contain Color values,
+     * not the {@link Node nodes} that represent the Color. The actual rendering
+     * should be left up to the {@link #cellFactoryProperty() cell factory},
+     * where it will take the Color value and create / update the display as
+     * necessary. 
+     */
+    public final ObjectProperty<ObservableList<T>> itemsProperty() {
+        if (items == null) {
+            items = new SimpleObjectProperty<>(this, "items"); //$NON-NLS-1$
+        }
+        return items;
+    }
+    private ObjectProperty<ObservableList<T>> items;
+    
+    /**
+     * Sets a new {@link ObservableList} as the items list underlying GridView.
+     * The old items list will be discarded.
+     */
+    public final void setItems(ObservableList<T> value) {
+        itemsProperty().set(value);
+    }
+
+    /**
+     * Returns the currently-in-use items list that is being used by the
+     * GridView.
+     */
+    public final ObservableList<T> getItems() {
+        return items == null ? null : items.get();
+    }
+
+    
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Stylesheet Handling                                                     *
+     *                                                                         *
+     **************************************************************************/
+
+    private static final String DEFAULT_STYLE_CLASS = "grid-view"; //$NON-NLS-1$
+
+    /** @treatAsPrivate */
+    private static class StyleableProperties {
+        private static final CssMetaData<GridView<?>,Number> HORIZONTAL_CELL_SPACING = 
+            new CssMetaData<GridView<?>,Number>("-fx-horizontal-cell-spacing", StyleConverter.getSizeConverter(), 12d) { //$NON-NLS-1$
+
+            @Override public Double getInitialValue(GridView<?> node) {
+                return node.getHorizontalCellSpacing();
+            }
+
+            @Override public boolean isSettable(GridView<?> n) {
+                return n.horizontalCellSpacing == null || !n.horizontalCellSpacing.isBound();
+            }
+
+            @Override
+            @SuppressWarnings("unchecked")
+            public StyleableProperty<Number> getStyleableProperty(GridView<?> n) {
+                return (StyleableProperty<Number>)n.horizontalCellSpacingProperty();
+            }
+        };
+        
+        private static final CssMetaData<GridView<?>,Number> VERTICAL_CELL_SPACING = 
+            new CssMetaData<GridView<?>,Number>("-fx-vertical-cell-spacing", StyleConverter.getSizeConverter(), 12d) { //$NON-NLS-1$
+
+            @Override public Double getInitialValue(GridView<?> node) {
+                return node.getVerticalCellSpacing();
+            }
+
+            @Override public boolean isSettable(GridView<?> n) {
+                return n.verticalCellSpacing == null || !n.verticalCellSpacing.isBound();
+            }
+
+            @Override
+            @SuppressWarnings("unchecked")
+            public StyleableProperty<Number> getStyleableProperty(GridView<?> n) {
+                return (StyleableProperty<Number>)n.verticalCellSpacingProperty();
+            }
+        };
+        
+        private static final CssMetaData<GridView<?>,Number> CELL_WIDTH = 
+            new CssMetaData<GridView<?>,Number>("-fx-cell-width", StyleConverter.getSizeConverter(), 64d) { //$NON-NLS-1$
+
+            @Override public Double getInitialValue(GridView<?> node) {
+                return node.getCellWidth();
+            }
+
+            @Override public boolean isSettable(GridView<?> n) {
+                return n.cellWidth == null || !n.cellWidth.isBound();
+            }
+
+            @Override
+            @SuppressWarnings("unchecked")
+            public StyleableProperty<Number> getStyleableProperty(GridView<?> n) {
+                return (StyleableProperty<Number>)n.cellWidthProperty();
+            }
+        };
+        
+        private static final CssMetaData<GridView<?>,Number> CELL_HEIGHT = 
+            new CssMetaData<GridView<?>,Number>("-fx-cell-height", StyleConverter.getSizeConverter(), 64d) { //$NON-NLS-1$
+
+            @Override public Double getInitialValue(GridView<?> node) {
+                return node.getCellHeight();
+            }
+
+            @Override public boolean isSettable(GridView<?> n) {
+                return n.cellHeight == null || !n.cellHeight.isBound();
+            }
+
+            @Override
+            @SuppressWarnings("unchecked")
+            public StyleableProperty<Number> getStyleableProperty(GridView<?> n) {
+                return (StyleableProperty<Number>)n.cellHeightProperty();
+            }
+        };
+        
+//        private static final CssMetaData<GridView<?>,HPos> HORIZONTAL_ALIGNMENT = 
+//            new CssMetaData<GridView<?>,HPos>("-fx-horizontal_alignment",
+//                new EnumConverter<HPos>(HPos.class), 
+//                HPos.CENTER) {
+//
+//            @Override public HPos getInitialValue(GridView node) {
+//                return node.getHorizontalAlignment();
+//            }
+//
+//            @Override public boolean isSettable(GridView n) {
+//                return n.horizontalAlignment == null || !n.horizontalAlignment.isBound();
+//            }
+//
+//            @Override public StyleableProperty<HPos> getStyleableProperty(GridView n) {
+//                return (StyleableProperty<HPos>)n.horizontalAlignmentProperty();
+//            }
+//        };
+            
+        private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
+        static {
+            final List<CssMetaData<? extends Styleable, ?>> styleables =
+                new ArrayList<>(Control.getClassCssMetaData());
+            styleables.add(HORIZONTAL_CELL_SPACING);
+            styleables.add(VERTICAL_CELL_SPACING);
+            styleables.add(CELL_WIDTH);
+            styleables.add(CELL_HEIGHT);
+//            styleables.add(HORIZONTAL_ALIGNMENT);
+            STYLEABLES = Collections.unmodifiableList(styleables);
+        }
+    }
+
+    /**
+     * @return The CssMetaData associated with this class, which may include the
+     * CssMetaData of its super classes.
+     */
+    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
+        return StyleableProperties.STYLEABLES;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
+        return getClassCssMetaData();
+    }
+}
diff --git a/src/org/controlsfx/control/HiddenSidesPane.java b/src/org/controlsfx/control/HiddenSidesPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..9aa37cb299ce78b3041bc7c64631a5c45f29dbd2
--- /dev/null
+++ b/src/org/controlsfx/control/HiddenSidesPane.java
@@ -0,0 +1,426 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.HiddenSidesPaneSkin;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.geometry.Side;
+import javafx.scene.Node;
+import javafx.scene.control.Skin;
+import javafx.util.Duration;
+
+/**
+ * A pane used to display a full-size content node and four initially hidden
+ * nodes on the four sides. The hidden nodes can be made visible by moving the
+ * mouse cursor to the edges (see {@link #setTriggerDistance(double)}) of the
+ * pane. The hidden node will appear (at its preferred width or height) with a
+ * short slide-in animation. The node will disappear again as soon as the mouse
+ * cursor exits it. A hidden node / side can also be pinned by calling
+ * {@link #setPinnedSide(Side)}. It will remain visible as long as it stays
+ * pinned.
+ * 
+ * <h3>Screenshot</h3> The following screenshots shows the right side node
+ * hovering over a table after it was made visible:
+ * 
+ * <center><img src="hiddenSidesPane.png" alt="Screenshot of HiddenSidesPane">
+ * 
+ * </center> <h3>Code Sample</h3>
+ * 
+ * <pre>
+ * HiddenSidesPane pane = new HiddenSidesPane();
+ * pane.setContent(new TableView());
+ * pane.setRight(new ListView());
+ * </pre>
+ */
+public class HiddenSidesPane extends ControlsFXControl {
+
+    /**
+     * Constructs a new pane with the given content node and the four side
+     * nodes. Each one of the side nodes may be null.
+     * 
+     * @param content
+     *            the primary node that will fill the entire width and height of
+     *            the pane
+     * @param top
+     *            the hidden node on the top side
+     * @param right
+     *            the hidden node on the right side
+     * @param bottom
+     *            the hidden node on the bottom side
+     * @param left
+     *            the hidden node on the left side
+     */
+    public HiddenSidesPane(Node content, Node top, Node right, Node bottom,
+            Node left) {
+        setContent(content);
+        setTop(top);
+        setRight(right);
+        setBottom(bottom);
+        setLeft(left);
+    }
+
+    /**
+     * Constructs a new pane with no content and no side nodes.
+     */
+    public HiddenSidesPane() {
+        this(null, null, null, null, null);
+    }
+
+    @Override
+    protected Skin<?> createDefaultSkin() {
+        return new HiddenSidesPaneSkin(this);
+    }
+
+    private DoubleProperty triggerDistance = new SimpleDoubleProperty(this,
+            "triggerDistance", 16); //$NON-NLS-1$
+
+    /**
+     * The property that stores the distance to the pane's edges that will
+     * trigger the appearance of the hidden side nodes.<br>
+     * Setting the property to zero or a negative value will disable this
+     * functionality, so a hidden side can only be made visible with
+     * {@link #setPinnedSide(Side)}.
+     * 
+     * @return the trigger distance property
+     */
+    public final DoubleProperty triggerDistanceProperty() {
+        return triggerDistance;
+    }
+
+    /**
+     * Returns the value of the trigger distance property.
+     * 
+     * @return the trigger distance property value
+     */
+    public final double getTriggerDistance() {
+        return triggerDistance.get();
+    }
+
+    /**
+     * Set the value of the trigger distance property. <br>
+     * Setting the property to zero or a negative value will disable this
+     * functionality, so a hidden side can only be made visible with
+     * {@link #setPinnedSide(Side)}.
+     * 
+     * @param distance
+     *            the new value for the trigger distance property
+     */
+    public final void setTriggerDistance(double distance) {
+        triggerDistance.set(distance);
+    }
+
+    // Content node support.
+
+    private ObjectProperty<Node> content = new SimpleObjectProperty<>(this,
+            "content"); //$NON-NLS-1$
+
+    /**
+     * The property that is used to store a reference to the content node. The
+     * content node will fill the entire width and height of the pane.
+     * 
+     * @return the content node property
+     */
+    public final ObjectProperty<Node> contentProperty() {
+        return content;
+    }
+
+    /**
+     * Returns the value of the content node property.
+     * 
+     * @return the content node property value
+     */
+    public final Node getContent() {
+        return contentProperty().get();
+    }
+
+    /**
+     * Sets the value of the content node property.
+     * 
+     * @param content
+     *            the new content node
+     */
+    public final void setContent(Node content) {
+        contentProperty().set(content);
+    }
+
+    // Top node support.
+
+    private ObjectProperty<Node> top = new SimpleObjectProperty<>(this,
+            "top"); //$NON-NLS-1$
+
+    /**
+     * The property used to store a reference to the node shown at the top side
+     * of the pane.
+     * 
+     * @return the hidden node at the top side of the pane
+     */
+    public final ObjectProperty<Node> topProperty() {
+        return top;
+    }
+
+    /**
+     * Returns the value of the top node property.
+     * 
+     * @return the top node property value
+     */
+    public final Node getTop() {
+        return topProperty().get();
+    }
+
+    /**
+     * Sets the value of the top node property.
+     * 
+     * @param top
+     *            the top node value
+     */
+    public final void setTop(Node top) {
+        topProperty().set(top);
+    }
+
+    // Right node support.
+
+    /**
+     * The property used to store a reference to the node shown at the right
+     * side of the pane.
+     * 
+     * @return the hidden node at the right side of the pane
+     */
+    private ObjectProperty<Node> right = new SimpleObjectProperty<>(this,
+            "right"); //$NON-NLS-1$
+
+    /**
+     * Returns the value of the right node property.
+     * 
+     * @return the right node property value
+     */
+    public final ObjectProperty<Node> rightProperty() {
+        return right;
+    }
+
+    /**
+     * Returns the value of the right node property.
+     * 
+     * @return the right node property value
+     */
+    public final Node getRight() {
+        return rightProperty().get();
+    }
+
+    /**
+     * Sets the value of the right node property.
+     * 
+     * @param right
+     *            the right node value
+     */
+    public final void setRight(Node right) {
+        rightProperty().set(right);
+    }
+
+    // Bottom node support.
+
+    /**
+     * The property used to store a reference to the node shown at the bottom
+     * side of the pane.
+     * 
+     * @return the hidden node at the bottom side of the pane
+     */
+    private ObjectProperty<Node> bottom = new SimpleObjectProperty<>(this,
+            "bottom"); //$NON-NLS-1$
+
+    /**
+     * Returns the value of the bottom node property.
+     * 
+     * @return the bottom node property value
+     */
+    public final ObjectProperty<Node> bottomProperty() {
+        return bottom;
+    }
+
+    /**
+     * Returns the value of the bottom node property.
+     * 
+     * @return the bottom node property value
+     */
+    public final Node getBottom() {
+        return bottomProperty().get();
+    }
+
+    /**
+     * Sets the value of the bottom node property.
+     * 
+     * @param bottom
+     *            the bottom node value
+     */
+    public final void setBottom(Node bottom) {
+        bottomProperty().set(bottom);
+    }
+
+    // Left node support.
+
+    /**
+     * The property used to store a reference to the node shown at the left side
+     * of the pane.
+     * 
+     * @return the hidden node at the left side of the pane
+     */
+    private ObjectProperty<Node> left = new SimpleObjectProperty<>(this,
+            "left"); //$NON-NLS-1$
+
+    /**
+     * Returns the value of the left node property.
+     * 
+     * @return the left node property value
+     */
+    public final ObjectProperty<Node> leftProperty() {
+        return left;
+    }
+
+    /**
+     * Returns the value of the left node property.
+     * 
+     * @return the left node property value
+     */
+    public final Node getLeft() {
+        return leftProperty().get();
+    }
+
+    /**
+     * Sets the value of the left node property.
+     * 
+     * @param left
+     *            the left node value
+     */
+    public final void setLeft(Node left) {
+        leftProperty().set(left);
+    }
+
+    // Pinned side support.
+
+    private ObjectProperty<Side> pinnedSide = new SimpleObjectProperty<>(
+            this, "pinnedSide"); //$NON-NLS-1$
+
+    /**
+     * Returns the pinned side property. The value of this property determines
+     * if one of the four hidden sides stays visible all the time.
+     * 
+     * @return the pinned side property
+     */
+    public final ObjectProperty<Side> pinnedSideProperty() {
+        return pinnedSide;
+    }
+
+    /**
+     * Returns the value of the pinned side property.
+     * 
+     * @return the pinned side property value
+     */
+    public final Side getPinnedSide() {
+        return pinnedSideProperty().get();
+    }
+
+    /**
+     * Sets the value of the pinned side property.
+     * 
+     * @param side
+     *            the new pinned side value
+     */
+    public final void setPinnedSide(Side side) {
+        pinnedSideProperty().set(side);
+    }
+
+    // slide in animation delay
+
+    private final ObjectProperty<Duration> animationDelay = new SimpleObjectProperty<>(
+            this, "animationDelay", Duration.millis(300)); //$NON-NLS-1$
+
+    /**
+     * Returns the animation delay property. The value of this property
+     * determines the delay before the hidden side slide in / slide out
+     * animation starts to play.
+     * 
+     * @return animation delay property
+     */
+    public final ObjectProperty<Duration> animationDelayProperty() {
+        return animationDelay;
+    }
+
+    /**
+     * Returns the animation delay
+     * 
+     * @return animation delay
+     */
+    public final Duration getAnimationDelay() {
+        return animationDelay.get();
+    }
+
+    /**
+     * Set the animation delay
+     * 
+     * @param duration
+     *            slide in animation delay
+     */
+    public final void setAnimationDelay(Duration duration) {
+        animationDelay.set(duration);
+    }
+
+    // slide in / slide out duration
+
+    private final ObjectProperty<Duration> animationDuration = new SimpleObjectProperty<>(
+            this, "animationDuration", Duration.millis(200)); //$NON-NLS-1$
+
+    /**
+     * Returns the animation duration property. The value of this property
+     * determines the fade in time for a hidden side to become visible.
+     * 
+     * @return animation delay property
+     */
+    public final ObjectProperty<Duration> animationDurationProperty() {
+        return animationDuration;
+    }
+
+    /**
+     * Returns the animation delay
+     * 
+     * @return animation delay
+     */
+    public final Duration getAnimationDuration() {
+        return animationDuration.get();
+    }
+
+    /**
+     * Set the animation delay
+     * 
+     * @param duration
+     *            animation duration
+     */
+    public final void setAnimationDuration(Duration duration) {
+        animationDuration.set(duration);
+    }
+}
diff --git a/src/org/controlsfx/control/HyperlinkLabel.java b/src/org/controlsfx/control/HyperlinkLabel.java
new file mode 100644
index 0000000000000000000000000000000000000000..abf3b90ef77d724ecfbdcb97c5a340ae235baf9e
--- /dev/null
+++ b/src/org/controlsfx/control/HyperlinkLabel.java
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.HyperlinkLabelSkin;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.event.EventTarget;
+import javafx.scene.control.Hyperlink;
+import javafx.scene.control.Skin;
+
+import com.sun.javafx.event.EventHandlerManager;
+
+/**
+ * A UI control that will convert the given text into a series of text labels
+ * and {@link Hyperlink hyperlinks}, based on the use of delimiter characters
+ * to specify where hyperlinks should appear. The delimiter characters are 
+ * square braces (that is, [ and ]). To create a hyperlink in a string you would
+ * therefore do something like 
+ * <code>hyperlinkLabel.setText("Click [here] for more information!");</code>,
+ * with the word 'here' appearing as a hyperlink that a use may click. This 
+ * approach therefore allows for hyperlinks to be easily embedded within a 
+ * label.
+ * 
+ * <p>Once hyperlinks have been declared in a text string, it is necessary to
+ * respond to the user interacting with the hyperlink (most commonly via mouse
+ * clicks). To do so, you register a single event handler for action events on
+ * the HyperlinkLabel instance, and then determine what to do within that 
+ * callback. For example:
+ * 
+ * <pre>
+ * {@code
+ * hyperlinkLabel.setOnAction(new EventHandler<ActionEvent>() {
+ *     public void handle(ActionEvent event) {
+ *         Hyperlink link = (Hyperlink)event.getSource();
+ *         final String str = link == null ? "" : link.getText();
+ *         switch(str) {
+ *             case "here": // do 'here' action
+ *                          break;
+ *             case "exit": // do exit action
+ *                          break;
+ *         }
+ *     }
+ * });}</pre>
+ * 
+ * <p>This simple single-handler approach was chosen over any more complex 
+ * per-hyperlink solution because it is anticipated that most use cases will 
+ * normally consist of one, or very few hyperlinks, and it was therefore unlikely
+ * that the increased API complexity would be warranted.
+ * 
+ * <h3>Screenshot</h3>
+ * <p>To demonstrate what a HyperlinkLabel looks like, refer to the screenshot
+ * below, when the text 
+ * <code>"Hello [world]! I [wonder] what hyperlink [you] [will] [click]"</code>
+ * was passed in to the HyperlinkLabel instance:
+ * 
+ * <br><br>
+ * <center><img src="hyperlinkLabel.PNG" alt="Screenshot of HyperlinkLabel"></center>
+ * 
+ * @see Hyperlink
+ * @see ActionEvent
+ */
+public class HyperlinkLabel extends ControlsFXControl implements EventTarget {
+    
+    /***************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+    private final EventHandlerManager eventHandlerManager =
+            new EventHandlerManager(this);
+    
+    
+    
+    /***************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Creates an empty HyperlinkLabel instance with no {@link #textProperty() text}
+     * specified.
+     */
+    public HyperlinkLabel() {
+        this(null);
+    }
+    
+    /**
+     * Creates a HyperlinkLabel instance with the given text value used as the 
+     * initial text.
+     * 
+     * @param text The text to display to the user.
+     */
+    public HyperlinkLabel(String text) {
+        setText(text);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new HyperlinkLabelSkin(this);
+    }
+    
+    
+    // --- text
+    private final StringProperty text = new SimpleStringProperty(this, "text"); //$NON-NLS-1$
+    
+    /**
+     * Return a {@link StringProperty} representing the text being displayed.
+     * @return a {@link StringProperty}.
+     */
+    public final StringProperty textProperty() { 
+        return text; 
+    }
+    
+    /**
+     * Return the text currently displayed.
+     * @return the text currently displayed.
+     */
+    public final String getText() {
+        return text.get();
+    }
+    
+    /**
+     * Set a new text to display to the user, using the delimiter characters [ and ]
+     * to indicate where hyperlinks should be displayed.
+     * @param value 
+     */
+    public final void setText(String value) {
+        text.set(value);
+    }
+    
+    
+    // --- onAction
+    private ObjectProperty<EventHandler<ActionEvent>> onAction;
+    
+    /**
+     * The action, which is invoked whenever a hyperlink is fired. This
+     * may be due to the user clicking on the hyperlink with the mouse, or by
+     * a touch event, or by a key press.
+     * @return an {@link ObjectProperty} representing the action.
+     */
+    public final ObjectProperty<EventHandler<ActionEvent>> onActionProperty() {
+        if (onAction == null) {
+            onAction = new SimpleObjectProperty<EventHandler<ActionEvent>>(this, "onAction") { //$NON-NLS-1$
+                @Override protected void invalidated() {
+                    eventHandlerManager.setEventHandler(ActionEvent.ACTION, get());
+                }
+            };
+        }
+        return onAction;
+    }
+
+    /**
+     * Sets a new EventHandler which will be invoked whenever a hyperlink is 
+     * fired.
+     * @param value 
+     */
+    public final void setOnAction(EventHandler<ActionEvent> value) {
+        onActionProperty().set( value);
+    }
+
+    /**
+     * 
+     * @return the action, which is invoked whenever a hyperlink is fired.
+     */
+    public final EventHandler<ActionEvent> getOnAction() {
+        return onAction == null ? null : onAction.get();
+    }
+
+    
+}
diff --git a/src/org/controlsfx/control/IndexedCheckModel.java b/src/org/controlsfx/control/IndexedCheckModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..acb77cd76a313ee6c2743657199c9b486d9a3b27
--- /dev/null
+++ b/src/org/controlsfx/control/IndexedCheckModel.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import javafx.collections.ObservableList;
+
+public interface IndexedCheckModel<T> extends CheckModel<T> {
+
+    /**
+     * Returns the item in the given index in the control.
+     */
+    public T getItem(int index);
+
+    /**
+     * Returns the index of the given item.
+     */
+    public int getItemIndex(T item);
+
+    /**
+     * Returns a read-only list of the currently checked indices in the control.
+     */
+    public ObservableList<Integer> getCheckedIndices();
+
+    /**
+     * Checks the given indices in the control
+     */
+    public void checkIndices(int... indices);
+
+    /**
+     * Unchecks the given index in the control
+     */
+    public void clearCheck(int index);
+
+    /**
+     * Returns true if the given index represents an item that is checked in the control.
+     */
+    public boolean isChecked(int index);
+
+    /**
+     * Checks the item in the given index in the control.
+     */
+    public void check(int index);
+
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/InfoOverlay.java b/src/org/controlsfx/control/InfoOverlay.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d9cf5d1990fe61fedf4ec278b8dad6b826f83db
--- /dev/null
+++ b/src/org/controlsfx/control/InfoOverlay.java
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.InfoOverlaySkin;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.scene.Node;
+import javafx.scene.control.Skin;
+import javafx.scene.image.ImageView;
+
+/**
+ * A simple UI control that allows for an information popup to be displayed over 
+ * a node to describe it in further detail. In some ways, it can be thought of 
+ * as a always visible tooltip (although by default it is collapsed so only the
+ * first line is shown - clicking on it will expand it to show all text).
+ * 
+ * <p>Shown below is a screenshot of the InfoOverlay control in both its 
+ * collapsed and expanded states:
+ * 
+ * <br>
+ * <center>
+ * <img src="infoOverlay.png" alt="Screenshot of InfoOverlay">
+ * </center>
+ */
+public class InfoOverlay extends ControlsFXControl {
+    
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+    
+    /**
+     * Constructs a default InfoOverlay control with no node or text. 
+     */
+    public InfoOverlay() {
+        this((Node)null, null);
+    }
+    
+    /**
+     * Attempts to construct an InfoOverlay instance using the given string
+     * to load an image, and to place the given text string over top of it.
+     * 
+     * @param imageUrl The image file to attempt to load.
+     * @param text The text to display over top of the image.
+     */
+    public InfoOverlay(String imageUrl, String text) {
+        this(new ImageView(imageUrl), text);
+    }
+
+    /**
+     * Constructs an InfoOverlay instance using the given Node (which can be
+     * an arbitrarily complex node / scenegraph, or a simple ImageView, for example),
+     * and places the given text string over top of it.
+     * 
+     * @param content The arbitrarily complex scenegraph over which the text will be displayed.
+     * @param text The text to display over top of the node.
+     */
+    public InfoOverlay(Node content, String text) {
+        getStyleClass().setAll(DEFAULT_STYLE_CLASS);
+
+        setContent(content);
+        setText(text);
+    }
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+    
+    /** {@inheritDoc} */   
+    @Override protected Skin<?> createDefaultSkin() {
+        return new InfoOverlaySkin(this);
+    }
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Properties                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    // --- content
+     private ObjectProperty<Node> content = new SimpleObjectProperty<>(this, "content"); //$NON-NLS-1$
+     
+    /**
+     * 
+     * @return an {@link ObjectProperty} containing the arbitrarily complex
+     * scenegraph over which the text will be displayed.
+     */
+    public final ObjectProperty<Node> contentProperty() {
+        return content;
+    }
+
+    /**
+     * Sets a new value for the {@link #contentProperty() }.
+     * @param content 
+     */
+    public final void setContent(Node content) {
+        contentProperty().set(content);
+    }
+
+    /**
+     * 
+     * @return the arbitrarily complex scenegraph over which the text will be 
+     * displayed.
+     */
+    public final Node getContent() {
+        return contentProperty().get();
+    }
+
+    
+    // --- text
+    
+    private StringProperty text = new SimpleStringProperty(this, "text"); //$NON-NLS-1$
+    
+    /**
+     * @return A {@link StringProperty} representing the text displayed over top
+     * of the {@link #contentProperty() content}.
+     */
+    public final StringProperty textProperty() {
+        return text;
+    }
+
+    /**
+     * 
+     * @return The text displayed over top of the {@link #contentProperty() content}.
+     */
+    public final String getText() {
+        return textProperty().get();
+    }
+
+    /**
+     * Specifies the text to display over top of the {@link #contentProperty() content}.
+     * @param text 
+     */
+    public final void setText(String text) {
+        textProperty().set(text);
+    }
+    
+    
+    // --- showOnHover
+    private BooleanProperty showOnHover = new SimpleBooleanProperty(this, "showOnHover", true); //$NON-NLS-1$
+    
+    /**
+     * 
+     * @return A {@link BooleanProperty} representing whether the overlay on 
+     * hover of the content node is showing.
+     */
+    public final BooleanProperty showOnHoverProperty() {
+        return showOnHover;
+    }
+
+    /**
+     * 
+     * @return whether the overlay on hover of the content node is showing.
+     */
+    public final boolean isShowOnHover() {
+        return showOnHoverProperty().get();
+    }
+
+    /**
+     * Specifies whether to show the overlay on hover of the content node (and 
+     * to hide it again when the content is no longer being hovered). By default 
+     * this is true. 
+     * @param value 
+     */
+    public final void setShowOnHover(boolean value) {
+        showOnHoverProperty().set(value);
+    }
+
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Stylesheet Handling                                                     *
+     *                                                                         *
+     **************************************************************************/
+    
+    private static final String DEFAULT_STYLE_CLASS = "info-overlay"; //$NON-NLS-1$
+
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(InfoOverlay.class, "info-overlay.css");
+    }
+}
diff --git a/src/org/controlsfx/control/ListSelectionView.java b/src/org/controlsfx/control/ListSelectionView.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c6d669d5ad44fb7901b4dda44c626a6eacc7ac2
--- /dev/null
+++ b/src/org/controlsfx/control/ListSelectionView.java
@@ -0,0 +1,370 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import static impl.org.controlsfx.i18n.Localization.asKey;
+import static impl.org.controlsfx.i18n.Localization.localize;
+
+import impl.org.controlsfx.skin.ListSelectionViewSkin;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.geometry.Orientation;
+import javafx.scene.Node;
+import javafx.scene.control.Cell;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.control.Skin;
+import javafx.util.Callback;
+
+/**
+ * A control used to perform a multi-selection via the help of two list views.
+ * Items can be moved from one list (source) to the other (target). This can be
+ * done by either double clicking on the list items or by using one of the
+ * "move" buttons between the two lists. Each list can be decorated with a
+ * header and a footer node. The default header nodes are simply two labels
+ * ("Available", "Selected").
+ *
+ * <h3>Screenshot</h3>
+ *
+ * <center><img src="list-selection-view.png" alt="Screenshot of ListSelectionView"></center>
+ *
+ * <h3>Code Example</h3>
+ *
+ * <pre>
+ * ListSelectionView&lt;String&gt; view = new ListSelectionView&lt;&gt;();
+ * view.getSourceItems().add(&quot;One&quot;, &quot;Two&quot;, &quot;Three&quot;);
+ * view.getTargetItems().add(&quot;Four&quot;, &quot;Five&quot;);
+ * </pre>
+ *
+ * @param <T>
+ *            the type of the list items
+ */
+public class ListSelectionView<T> extends ControlsFXControl {
+
+    private static final String DEFAULT_STYLECLASS = "list-selection-view";
+
+    /**
+     * Constructs a new dual list view.
+     */
+    public ListSelectionView() {
+        getStyleClass().add(DEFAULT_STYLECLASS);
+
+        Label sourceHeader = new Label(
+                localize(asKey("listSelectionView.header.source")));
+        sourceHeader.getStyleClass().add("list-header-label");
+        sourceHeader.setId("source-header-label");
+        setSourceHeader(sourceHeader);
+
+        Label targetHeader = new Label(
+                localize(asKey("listSelectionView.header.target")));
+        targetHeader.getStyleClass().add("list-header-label");
+        targetHeader.setId("target-header-label");
+        setTargetHeader(targetHeader);
+    }
+
+    @Override
+    protected Skin<ListSelectionView<T>> createDefaultSkin() {
+        return new ListSelectionViewSkin<>(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(ListSelectionView.class, "listselectionview.css");
+    }
+
+    private final ObjectProperty<Node> sourceHeader = new SimpleObjectProperty<>(
+            this, "sourceHeader");
+
+    /**
+     * A property used to store a reference to a node that will be displayed
+     * above the source list view. The default node is a {@link Label}
+     * displaying the text "Available".
+     *
+     * @return the property used to store the source header node
+     */
+    public final ObjectProperty<Node> sourceHeaderProperty() {
+        return sourceHeader;
+    }
+
+    /**
+     * Returns the value of {@link #sourceHeaderProperty()}.
+     *
+     * @return the source header node
+     */
+    public final Node getSourceHeader() {
+        return sourceHeader.get();
+    }
+
+    /**
+     * Sets the value of {@link #sourceHeaderProperty()}.
+     *
+     * @param node
+     *            the new header node to use for the source list
+     */
+    public final void setSourceHeader(Node node) {
+        sourceHeader.set(node);
+    }
+
+    private final ObjectProperty<Node> sourceFooter = new SimpleObjectProperty<>(
+            this, "sourceFooter");
+
+    /**
+     * A property used to store a reference to a node that will be displayed
+     * below the source list view. The default node is a node with two buttons
+     * for easily selecting / deselecting all elements in the list view.
+     *
+     * @return the property used to store the source footer node
+     */
+    public final ObjectProperty<Node> sourceFooterProperty() {
+        return sourceFooter;
+    }
+
+    /**
+     * Returns the value of {@link #sourceFooterProperty()}.
+     *
+     * @return the source footer node
+     */
+    public final Node getSourceFooter() {
+        return sourceFooter.get();
+    }
+
+    /**
+     * Sets the value of {@link #sourceFooterProperty()}.
+     *
+     * @param node
+     *            the new node shown below the source list
+     */
+    public final void setSourceFooter(Node node) {
+        sourceFooter.set(node);
+    }
+
+    private final ObjectProperty<Node> targetHeader = new SimpleObjectProperty<>(
+            this, "targetHeader");
+
+    /**
+     * A property used to store a reference to a node that will be displayed
+     * above the target list view. The default node is a {@link Label}
+     * displaying the text "Selected".
+     *
+     * @return the property used to store the target header node
+     */
+    public final ObjectProperty<Node> targetHeaderProperty() {
+        return targetHeader;
+    }
+
+    /**
+     * Returns the value of {@link #targetHeaderProperty()}.
+     *
+     * @return the source header node
+     */
+    public final Node getTargetHeader() {
+        return targetHeader.get();
+    }
+
+    /**
+     * Sets the value of {@link #targetHeaderProperty()}.
+     *
+     * @param node
+     *            the new node shown above the target list
+     */
+    public final void setTargetHeader(Node node) {
+        targetHeader.set(node);
+    }
+
+    private final ObjectProperty<Node> targetFooter = new SimpleObjectProperty<>(
+            this, "targetFooter");
+
+    /**
+     * A property used to store a reference to a node that will be displayed
+     * below the target list view. The default node is a node with two buttons
+     * for easily selecting / deselecting all elements in the list view.
+     *
+     * @return the property used to store the source footer node
+     */
+    public final ObjectProperty<Node> targetFooterProperty() {
+        return targetFooter;
+    }
+
+    /**
+     * Returns the value of {@link #targetFooterProperty()}.
+     *
+     * @return the source header node
+     */
+    public final Node getTargetFooter() {
+        return targetFooter.get();
+    }
+
+    /**
+     * Sets the value of {@link #targetFooterProperty()}.
+     *
+     * @param node
+     *            the new node shown below the target list
+     */
+    public final void setTargetFooter(Node node) {
+        targetFooter.set(node);
+    }
+
+    private ObjectProperty<ObservableList<T>> sourceItems;
+
+    /**
+     * Sets the underlying data model for the ListView. Note that it has a
+     * generic type that must match the type of the ListView itself.
+     */
+    public final void setSourceItems(ObservableList<T> value) {
+        sourceItemsProperty().set(value);
+    }
+
+    /**
+     * Returns an {@link ObservableList} that contains the items currently being
+     * shown to the user in the source list. This may be null if
+     * {@link #setSourceItems(javafx.collections.ObservableList)} has previously
+     * been called, however, by default it is an empty ObservableList.
+     *
+     * @return An ObservableList containing the items to be shown to the user in
+     *         the source list, or null if the items have previously been set to
+     *         null.
+     */
+    public final ObservableList<T> getSourceItems() {
+        return sourceItemsProperty().get();
+    }
+
+    /**
+     * The underlying data model for the source list view. Note that it has a
+     * generic type that must match the type of the source list view itself.
+     */
+    public final ObjectProperty<ObservableList<T>> sourceItemsProperty() {
+        if (sourceItems == null) {
+            sourceItems = new SimpleObjectProperty<>(this, "sourceItems",
+                    FXCollections.observableArrayList());
+        }
+        return sourceItems;
+    }
+
+    private ObjectProperty<ObservableList<T>> targetItems;
+
+    /**
+     * Sets the underlying data model for the ListView. Note that it has a
+     * generic type that must match the type of the ListView itself.
+     */
+    public final void setTargetItems(ObservableList<T> value) {
+        targetItemsProperty().set(value);
+    }
+
+    /**
+     * Returns an {@link ObservableList} that contains the items currently being
+     * shown to the user in the target list. This may be null if
+     * {@link #setTargetItems(javafx.collections.ObservableList)} has previously
+     * been called, however, by default it is an empty ObservableList.
+     *
+     * @return An ObservableList containing the items to be shown to the user in
+     *         the target list, or null if the items have previously been set to
+     *         null.
+     */
+    public final ObservableList<T> getTargetItems() {
+        return targetItemsProperty().get();
+    }
+
+    /**
+     * The underlying data model for the target list view. Note that it has a
+     * generic type that must match the type of the source list view itself.
+     */
+    public final ObjectProperty<ObservableList<T>> targetItemsProperty() {
+        if (targetItems == null) {
+            targetItems = new SimpleObjectProperty<>(this, "targetItems",
+                    FXCollections.observableArrayList());
+        }
+        return targetItems;
+    }
+
+    // --- Orientation
+    private final ObjectProperty<Orientation> orientation = new SimpleObjectProperty<>(
+            this, "orientation", Orientation.HORIZONTAL); //$NON-NLS-1$;
+
+    /**
+     * The {@link Orientation} of the {@code ListSelectionView} - this can
+     * either be horizontal or vertical.
+     */
+    public final ObjectProperty<Orientation> orientationProperty() {
+        return orientation;
+    }
+
+    /**
+     * Sets the {@link Orientation} of the {@code ListSelectionView} - this can
+     * either be horizontal or vertical.
+     */
+    public final void setOrientation(Orientation value) {
+        orientationProperty().set(value);
+    };
+
+    /**
+     * Returns the {@link Orientation} of the {@code ListSelectionView} - this
+     * can either be horizontal or vertical.
+     */
+    public final Orientation getOrientation() {
+        return orientation.get();
+    }
+
+    // --- Cell Factory
+    private ObjectProperty<Callback<ListView<T>, ListCell<T>>> cellFactory;
+
+    /**
+     * Sets a new cell factory to use by both list views. This forces all old
+     * {@link ListCell}'s to be thrown away, and new ListCell's created with the
+     * new cell factory.
+     */
+    public final void setCellFactory(Callback<ListView<T>, ListCell<T>> value) {
+        cellFactoryProperty().set(value);
+    }
+
+    /**
+     * Returns the current cell factory.
+     */
+    public final Callback<ListView<T>, ListCell<T>> getCellFactory() {
+        return cellFactory == null ? null : cellFactory.get();
+    }
+
+    /**
+     * <p>
+     * Setting a custom cell factory has the effect of deferring all cell
+     * creation, allowing for total customization of the cell. Internally, the
+     * ListView is responsible for reusing ListCells - all that is necessary is
+     * for the custom cell factory to return from this function a ListCell which
+     * might be usable for representing any item in the ListView.
+     *
+     * <p>
+     * Refer to the {@link Cell} class documentation for more detail.
+     */
+    public final ObjectProperty<Callback<ListView<T>, ListCell<T>>> cellFactoryProperty() {
+        if (cellFactory == null) {
+            cellFactory = new SimpleObjectProperty<>(this, "cellFactory");
+        }
+        return cellFactory;
+    }
+}
diff --git a/src/org/controlsfx/control/MaskerPane.java b/src/org/controlsfx/control/MaskerPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..0003d4669a31487e236970977e7652dd402d0c7b
--- /dev/null
+++ b/src/org/controlsfx/control/MaskerPane.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.MaskerPaneSkin;
+import javafx.beans.property.*;
+import javafx.scene.Node;
+import javafx.scene.control.ProgressIndicator;
+import javafx.scene.control.Skin;
+import javafx.scene.layout.StackPane;
+
+
+/**
+ * <p>MaskerPane is designed to be placed alongside other controls in a {@link StackPane},
+ * in order to visually mask these controls, preventing them from being accessed
+ * for a short period of time. This comes in handy whenever waiting on asynchronous
+ * code to finish, and you do not want the user to be able to modify the state
+ * of the UI while waiting.</p>
+ *
+ * <p>To use this control, it is necessary to place it as the last child in a {@link StackPane},
+ * with the other children being masked by this MaskerPane when visible. Simply use
+ * {@link #setVisible(boolean)} to toggle between visible states.</p>
+ */
+public class MaskerPane extends ControlsFXControl {
+
+    /**************************************************************************
+     *
+     * Constructors
+     *
+     **************************************************************************/
+
+    /**
+     * Construct a new {@link MaskerPane}
+     */
+    public MaskerPane() { getStyleClass().add("masker-pane"); } //$NON-NLS-1$
+
+
+
+    /**************************************************************************
+     *
+     * Properties
+     *
+     **************************************************************************/
+
+    // -- Background Color
+
+    // -- Progress
+    private final DoubleProperty progress = new SimpleDoubleProperty(this, "progress", -1.0); //$NON-NLS-1$
+    public final DoubleProperty progressProperty() { return progress; }
+    public final double getProgress() { return progress.get(); }
+    public final void setProgress(double progress) { this.progress.set(progress); }
+
+    // -- Progress Node
+    private final ObjectProperty<Node> progressNode = new SimpleObjectProperty<Node>() {
+        {
+            ProgressIndicator node = new ProgressIndicator();
+            node.progressProperty().bind(progress);
+            setValue(node);
+        }
+
+        @Override public String getName() { return "progressNode"; } //$NON-NLS-1$
+        @Override public Object getBean() { return MaskerPane.this; }
+    };
+    public final ObjectProperty<Node> progressNodeProperty() { return progressNode; }
+    public final Node getProgressNode() { return progressNode.get();}
+    public final void setProgressNode(Node progressNode) { this.progressNode.set(progressNode); }
+
+    // -- Progress Visibility
+    private final BooleanProperty progressVisible = new SimpleBooleanProperty(this, "progressVisible", true); //$NON-NLS-1$
+    public final BooleanProperty progressVisibleProperty() { return progressVisible; }
+    public final boolean getProgressVisible() { return progressVisible.get(); }
+    public final void setProgressVisible(boolean progressVisible) { this.progressVisible.set(progressVisible); }
+
+    // -- Text
+    private final StringProperty text = new SimpleStringProperty(this, "text", "Please Wait..."); //$NON-NLS-1$
+    public final StringProperty textProperty() { return text; }
+    public final String getText() { return text.get(); }
+    public final void setText(String text) { this.text.set(text); }
+
+
+
+    /**************************************************************************
+     *
+     * Interface implementation
+     *
+     **************************************************************************/
+
+    /** {@inheritDoc} */
+    @Override protected Skin<?> createDefaultSkin() { return new MaskerPaneSkin(this); }
+
+    /** {@inheritDoc} */
+    @Override  public String getUserAgentStylesheet() { return getUserAgentStylesheet(MaskerPane.class, "maskerpane.css"); } //$NON-NLS-1$
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/MasterDetailPane.java b/src/org/controlsfx/control/MasterDetailPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..18f106112aaec20778c8feb260446cc456412492
--- /dev/null
+++ b/src/org/controlsfx/control/MasterDetailPane.java
@@ -0,0 +1,386 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.MasterDetailPaneSkin;
+
+import java.util.Objects;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.geometry.Pos;
+import javafx.geometry.Side;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.control.Skin;
+
+/**
+ * A master / detail pane is used to display two nodes with a strong
+ * relationship to each other. Most of the time the user works with the
+ * information displayed in the master node but every once in a while additional
+ * information is required and can be made visible via the detail node. By
+ * default the detail appears with a short slide-in animation and disappears
+ * with a slide-out. This control allows the detail node to be positioned in
+ * four different locations (top, bottom, left, or right). 
+ * <h3>Screenshot</h3>
+ * To better describe what a master / detail pane is, please refer to the picture
+ * below:
+ * <center><img src="masterDetailPane.png" alt="Screenshot of MasterDetailPane"></center>
+ * <h3>Code Sample</h3>
+ * <pre>
+ * {@code
+ * MasterDetailPane pane = new MasterDetailPane();
+ * pane.setMasterNode(new TableView());
+ * pane.setDetailNode(new PropertySheet());
+ * pane.setDetailSide(Side.RIGHT);
+ * pane.setShowDetailNode(true);
+ * }</pre>
+ */
+public class MasterDetailPane extends ControlsFXControl {
+
+    /**
+     * Constructs a new pane.
+     * 
+     * @param side
+     *            the position where the detail will be shown (top, bottom,
+     *            left, right)
+     * @param masterNode
+     *            the master node (always visible)
+     * @param detailNode
+     *            the detail node (slides in and out)
+     * @param showDetail
+     *            the initial state of the detail node (shown or hidden)
+     */
+    public MasterDetailPane(Side side, Node masterNode, Node detailNode,
+            boolean showDetail) {
+
+        super();
+
+        Objects.requireNonNull(side);
+        Objects.requireNonNull(masterNode);
+        Objects.requireNonNull(detailNode);
+        
+        getStyleClass().add("master-detail-pane"); //$NON-NLS-1$
+
+        setDetailSide(side);
+        setMasterNode(masterNode);
+        setDetailNode(detailNode);
+        setShowDetailNode(showDetail);
+
+        switch (side) {
+        case BOTTOM:
+        case RIGHT:
+            setDividerPosition(.8);
+            break;
+        case TOP:
+        case LEFT:
+            setDividerPosition(.2);
+            break;
+        default:
+            break;
+
+        }
+    }
+
+    /**
+     * Constructs a new pane with two placeholder nodes.
+     * 
+     * @param pos
+     *            the position where the details will be shown (top, bottom,
+     *            left, right)
+     * @param showDetail
+     *            the initial state of the detail node (shown or hidden)
+     */
+    public MasterDetailPane(Side pos, boolean showDetail) {
+        this(pos, new Placeholder(true), new Placeholder(false), showDetail);
+    }
+
+    /**
+     * Constructs a new pane with two placeholder nodes. The detail node will be
+     * shown.
+     * 
+     * @param pos
+     *            the position where the details will be shown (top, bottom,
+     *            left, right)
+     */
+    public MasterDetailPane(Side pos) {
+        this(pos, new Placeholder(true), new Placeholder(false), true);
+    }
+
+    /**
+     * Constructs a new pane with two placeholder nodes. The detail node will be
+     * shown and to the right of the master node.
+     */
+    public MasterDetailPane() {
+        this(Side.RIGHT, new Placeholder(true), new Placeholder(false), true);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new MasterDetailPaneSkin(this);
+    }
+    
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(MasterDetailPane.class, "masterdetailpane.css");
+    }
+
+    // Detail postion support
+
+    private final ObjectProperty<Side> detailSide = new SimpleObjectProperty<>(
+            this, "detailSide", Side.RIGHT); //$NON-NLS-1$
+
+    /**
+     * The property used to store the side where the detail node will be shown.
+     * 
+     * @return the details side property
+     */
+    public final ObjectProperty<Side> detailSideProperty() {
+        return detailSide;
+    }
+
+    /**
+     * Returns the value of the detail side property.
+     * 
+     * @return the side where the detail node will be shown (left, right, top,
+     *         bottom)
+     */
+    public final Side getDetailSide() {
+        return detailSideProperty().get();
+    }
+
+    /**
+     * Sets the value of the detail side property.
+     * 
+     * @param side
+     *            the side where the detail node will be shown (left, right,
+     *            top, bottom)
+     */
+    public final void setDetailSide(Side side) {
+        Objects.requireNonNull(side);
+        detailSideProperty().set(side);
+    }
+
+    // Show / hide detail node support.
+
+    private final BooleanProperty showDetailNode = new SimpleBooleanProperty(
+            this, "showDetailNode", true); //$NON-NLS-1$
+
+    /**
+     * The property used to store the visibility of the detail node.
+     * 
+     * @return true if the pane is currently expanded (shows the detail node)
+     */
+    public final BooleanProperty showDetailNodeProperty() {
+        return showDetailNode;
+    }
+
+    /**
+     * Returns the value of the "show detail node" property.
+     * 
+     * @return true if the pane is currently expanded (shows the detail node)
+     */
+    public final boolean isShowDetailNode() {
+        return showDetailNodeProperty().get();
+    }
+
+    /**
+     * Sets the value of the "show detail node" property.
+     * 
+     * @param show
+     *            if true the pane will show the detail node
+     */
+    public final void setShowDetailNode(boolean show) {
+        showDetailNodeProperty().set(show);
+    }
+
+    // Master node support.
+
+    private final ObjectProperty<Node> masterNode = new SimpleObjectProperty<>(
+            this, "masterNode"); //$NON-NLS-1$
+
+    /**
+     * The property used to store the master node.
+     * 
+     * @return the master node property
+     */
+    public final ObjectProperty<Node> masterNodeProperty() {
+        return masterNode;
+    }
+
+    /**
+     * Returns the value of the master node property.
+     * 
+     * @return the master node
+     */
+    public final Node getMasterNode() {
+        return masterNodeProperty().get();
+    }
+
+    /**
+     * Sets the value of the master node property.
+     * 
+     * @param node
+     *            the new master node
+     */
+    public final void setMasterNode(Node node) {
+        Objects.requireNonNull(node);
+        masterNodeProperty().set(node);
+    }
+
+    // Detail node support.
+
+    private final ObjectProperty<Node> detailNode = new SimpleObjectProperty<>(
+            this, "detailNode"); //$NON-NLS-1$
+
+    /**
+     * The property used to store the detail node.
+     * 
+     * @return the detail node property
+     */
+    public final ObjectProperty<Node> detailNodeProperty() {
+        return detailNode;
+    }
+
+    /**
+     * Returns the value of the detail node property.
+     * 
+     * @return the detail node
+     */
+    public final Node getDetailNode() {
+        return detailNodeProperty().get();
+    }
+
+    /**
+     * Sets the value of the detail node property.
+     * 
+     * @param node
+     *            the new master node
+     */
+    public final void setDetailNode(Node node) {
+        Objects.requireNonNull(node);
+        detailNodeProperty().set(node);
+    }
+
+    // Animation support.
+
+    private final BooleanProperty animated = new SimpleBooleanProperty(this,
+            "animated", true); //$NON-NLS-1$
+
+    /**
+     * The property used to store the "animated" flag. If true then the detail
+     * node will be shown / hidden with a short slide in / out animation.
+     * 
+     * @return the "animated" property
+     */
+    public final BooleanProperty animatedProperty() {
+        return animated;
+    }
+
+    /**
+     * Returns the value of the "animated" property.
+     * 
+     * @return true if the detail node will be shown with a short animation
+     *         (slide in)
+     */
+    public final boolean isAnimated() {
+        return animatedProperty().get();
+    }
+
+    /**
+     * Sets the value of the "animated" property.
+     * 
+     * @param animated
+     *            if true the detail node will be shown with a short animation
+     *            (slide in)
+     */
+    public final void setAnimated(boolean animated) {
+        animatedProperty().set(animated);
+    }
+
+    private DoubleProperty dividerPosition = new SimpleDoubleProperty(this,
+            "dividerPosition", .33); //$NON-NLS-1$
+
+    /**
+     * Stores the location of the divider.
+     * 
+     * @return the divider location
+     */
+    public final DoubleProperty dividerPositionProperty() {
+        return dividerPosition;
+    }
+
+    /**
+     * Returns the value of the divider position property.
+     * 
+     * @return the position of the divider
+     */
+    public final double getDividerPosition() {
+        return dividerPosition.get();
+    }
+
+    /**
+     * Sets the value of the divider position property.
+     * 
+     * @param position
+     *            the new divider position.
+     */
+    public final void setDividerPosition(double position) {
+        /**
+         * See https://bitbucket.org/controlsfx/controlsfx/issue/145/divider-position-in-masterdetailpane-is
+         * 
+         * Thie work-around is not the best ever found but at least it works.
+         */
+        if(getDividerPosition() == position){
+            dividerPosition.set(-1);
+        }
+        dividerPosition.set(position);
+    }
+
+    /*
+     * A placeholder for the constructors that do not accept a master or a
+     * detail node.
+     */
+    private static final class Placeholder extends Label {
+
+        public Placeholder(boolean master) {
+            super(master ? "Master" : "Detail"); //$NON-NLS-1$ //$NON-NLS-2$
+
+            setAlignment(Pos.CENTER);
+
+            if (master) {
+                setStyle("-fx-background-color: -fx-background;"); //$NON-NLS-1$
+            } else {
+                setStyle("-fx-background-color: derive(-fx-background, -10%);"); //$NON-NLS-1$
+            }
+        }
+    }
+}
diff --git a/src/org/controlsfx/control/NotificationPane.java b/src/org/controlsfx/control/NotificationPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..4bb82b9e55a687c76435a1c6326c07722149b279
--- /dev/null
+++ b/src/org/controlsfx/control/NotificationPane.java
@@ -0,0 +1,630 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.NotificationPaneSkin;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyBooleanProperty;
+import javafx.beans.property.ReadOnlyBooleanWrapper;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.event.EventType;
+import javafx.scene.Node;
+import javafx.scene.control.Skin;
+import javafx.scene.web.WebView;
+
+import org.controlsfx.control.action.Action;
+
+/**
+ * The NotificationPane control is a container control that, when prompted by
+ * the {@link #show()} method, will show a non-modal message to the user. The
+ * notification appears as a bar that will slide in to their application window,
+ * either from the top or the bottom of the NotificationPane (based on 
+ * {@link #showFromTopProperty()}) wherever that may be in the scenegraph.
+ * 
+ * <h3>Alternative Styling</h3>
+ * <p>As is visible in the screenshots further down this documentation, 
+ * there are two different styles supported by the NotificationPane control.
+ * Firstly, there is the default style based on the JavaFX Modena look. The 
+ * alternative style is what is currently referred to as the 'dark' look. To 
+ * enable this functionality, simply do the following:
+ * 
+ * <pre>
+ * {@code
+ * NotificationPane notificationPane = new NotificationPane();   
+ * notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK);
+ * }</pre>
+ * 
+ * <h3>Screenshots</h3>
+ * <p>To better explain NotificationPane, here is a table showing both the
+ * default and dark look for the NotificationPane on a Windows machine (although
+ * that shouldn't impact the visuals a great deal). Also, to show the difference
+ * between top and bottom placement, these two modes are also captured in the
+ * screenshots below:
+ * 
+ * <br>
+ * <center>
+ * <table style="border: 1px solid gray; max-width:750px" summary="NotificationPane Screenshots">
+ *   <tr>
+ *     <th width="200"><center><h3>Setting</h3></center></th>
+ *     <th width="520"><center><h3>Screenshot</h3></center></th>
+ *   </tr>
+ *   <tr>
+ *     <td valign="top" style="text-align:center;"><strong>Light theme from top:</strong></td>
+ *     <td><center><img src="notication-pane-light-top.png" alt="Screenshot of NotificationPane - Light theme from top"></center></td>
+ *   </tr>
+ *   <tr>
+ *     <td valign="top" style="text-align:center;"><strong>Light theme from bottom:</strong></td>
+ *     <td><center><img src="notication-pane-light-bottom.png" alt="Screenshot of NotificationPane - Light theme from bottom"></center></td>
+ *   </tr>
+ *   <tr>
+ *     <td valign="top" style="text-align:center;"><strong>Dark theme from top:</strong></td>
+ *     <td><center><img src="notication-pane-dark-top.png" alt="Screenshot of NotificationPane - Dark theme from top"></center></td>
+ *   </tr>
+ *   <tr>
+ *     <td valign="top" style="text-align:center;"><strong>Dark theme from bottom:</strong></td>
+ *     <td><center><img src="notication-pane-dark-bottom.png" alt="Screenshot of NotificationPane - Dark theme from bottom"></center></td>
+ *   </tr>
+ * </table>
+ * </center>
+ * 
+ * <h3>Code Examples</h3>
+ * 
+ * <p>NotificationPane is a conceptually very simple control - you simply create
+ * your user interface as you normally would, and then wrap it inside the 
+ * NotificationPane. You can then show a notification bar on top of your content
+ * simply by calling {@link #show()} on the notification bar. Here is an example: 
+ * 
+ * <pre>
+ * {@code
+ * // Create a WebView
+ * WebView webView = new WebView();
+ * 
+ * // Wrap it inside a NotificationPane
+ * NotificationPane notificationPane = new NotificationPane(webView);
+ * 
+ * // and put the NotificationPane inside a Tab
+ * Tab tab1 = new Tab("Tab 1");
+ * tab1.setContent(notificationPane);
+ * 
+ * // and the Tab inside a TabPane. We just have one tab here, but of course 
+ * // you can have more!
+ * TabPane tabPane = new TabPane();
+ * tabPane.getTabs().addAll(tab1);
+ * }</pre>
+ * 
+ * <p>Now that the notification pane is installed inside the tab, at some point
+ * later in you application lifecycle, you can do something like the following
+ * to have the notification bar slide into view:
+ * 
+ * <pre>
+ * {@code 
+ * notificationPane.setText("Do you want to save your password?");
+ * notificationPane.getActions().add(new AbstractAction("Save Password") {
+ *     public void execute(ActionEvent ae) {
+ *         // do save...
+ *           
+ *         // then hide...
+ *         notificationPane.hide();
+ *     }
+ * }}</pre>
+ * 
+ * @see Action
+ */
+public class NotificationPane extends ControlsFXControl {
+    
+    /***************************************************************************
+     * 
+     * Static fields
+     * 
+     **************************************************************************/
+    
+    public static final String STYLE_CLASS_DARK = "dark"; //$NON-NLS-1$
+    
+    /**
+     * Called when the NotificationPane <b>will</b> be shown.
+     */
+    public static final EventType<Event> ON_SHOWING =
+            new EventType<>(Event.ANY, "NOTIFICATION_PANE_ON_SHOWING"); //$NON-NLS-1$
+
+    /**
+     * Called when the NotificationPane shows.
+     */
+    public static final EventType<Event> ON_SHOWN =
+            new EventType<>(Event.ANY, "NOTIFICATION_PANE_ON_SHOWN"); //$NON-NLS-1$
+
+    /**
+     * Called when the NotificationPane <b>will</b> be hidden.
+     */
+    public static final EventType<Event> ON_HIDING =
+            new EventType<>(Event.ANY, "NOTIFICATION_PANE_ON_HIDING"); //$NON-NLS-1$
+
+    /**
+     * Called when the NotificationPane is hidden.
+     */
+    public static final EventType<Event> ON_HIDDEN =
+            new EventType<>(Event.ANY, "NOTIFICATION_PANE_ON_HIDDEN"); //$NON-NLS-1$
+    
+    
+    
+    /***************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Creates an instance of NotificationPane with no 
+     * {@link #contentProperty() content}, {@link #textProperty() text}, 
+     * {@link #graphicProperty() graphic} properties set, and no 
+     * {@link #getActions() actions} specified.
+     */
+    public NotificationPane() {
+        this(null);
+    }
+    
+    /**
+     * Creates an instance of NotificationPane with the 
+     * {@link #contentProperty() content} property set, but no 
+     * {@link #textProperty() text} or
+     * {@link #graphicProperty() graphic} property set, and no
+     * {@link #getActions() actions} specified.
+     * 
+     * @param content The content to show in the NotificationPane behind where
+     *      the notification bar will appear, that is, the content 
+     *      <strong>will not</strong>appear in the notification bar. 
+     */
+    public NotificationPane(Node content) {
+        getStyleClass().add(DEFAULT_STYLE_CLASS);
+        setContent(content);
+        
+        updateStyleClasses();
+    }
+    
+    
+    
+    /***************************************************************************
+     * 
+     * Overriding public API
+     * 
+     **************************************************************************/
+    
+    /** {@inheritDoc} */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new NotificationPaneSkin(this);
+    }
+    
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(NotificationPane.class, "notificationpane.css");
+    }
+    
+    /***************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+    
+    // --- content
+    private ObjectProperty<Node> content = new SimpleObjectProperty<>(this, "content"); //$NON-NLS-1$
+    
+    /**
+     * The content property represents what is shown in the scene 
+     * <strong>that is not within</strong> the notification bar. In other words,
+     * it is what the notification bar should appear on top of. For example, in
+     * the scenario where you are using a {@link WebView} to show to the user
+     * websites, and you want to popup up a notification bar to save a password,
+     * the content would be the {@link WebView}. Refer to the 
+     * {@link NotificationPane} class documentation for more details.
+     *  
+     * @return A property representing the content of this NotificationPane.
+     */
+    public final ObjectProperty<Node> contentProperty() {
+        return content;
+    }
+    
+    /**
+     * Set the content to be shown in the scene, 
+     * <strong>that is not within</strong> the notification bar.
+     * @param value 
+     */
+    public final void setContent(Node value) {
+        this.content.set(value); 
+    }
+    
+    /**
+     * 
+     * @return The content shown in the scene.
+     */
+    public final Node getContent() {
+        return content.get();
+    }
+    
+    
+    // --- text
+    private StringProperty text = new SimpleStringProperty(this, "text"); //$NON-NLS-1$
+    
+    /**
+     * The text property represents the text to show within the popup 
+     * notification bar that appears on top of the 
+     * {@link #contentProperty() content} that is within the NotificationPane.
+     * 
+     * @return A property representing the text shown in the notification bar.
+     */
+    public final StringProperty textProperty() {
+        return text;
+    }
+    
+    /**
+     * Sets the text to show within the popup 
+     * notification bar that appears on top of the 
+     * {@link #contentProperty() content}.
+     * @param value 
+     */
+    public final void setText(String value) {
+        this.text.set(value); 
+    }
+    
+    /**
+     * 
+     * @return the text showing within the popup 
+     * notification bar that appears on top of the 
+     * {@link #contentProperty() content}.
+     */
+    public final String getText() {
+        return text.get();
+    }
+    
+    
+    // --- graphic
+    private ObjectProperty<Node> graphic = new SimpleObjectProperty<>(this, "graphic"); //$NON-NLS-1$
+    
+    /**
+     * The graphic property represents the {@link Node} to show within the popup 
+     * notification bar that appears on top of the 
+     * {@link #contentProperty() content} that is within the NotificationPane.
+     * Despite the term 'graphic', this can be an arbitrarily complex scenegraph
+     * in its own right.
+     * 
+     * @return A property representing the graphic shown in the notification bar.
+     */
+    public final ObjectProperty<Node> graphicProperty() {
+        return graphic;
+    }
+    
+    /**
+     * Sets the {@link Node} to show within the popup 
+     * notification bar.
+     * @param value 
+     */
+    public final void setGraphic(Node value) {
+        this.graphic.set(value); 
+    }
+    
+    /**
+     * 
+     * @return the {@link Node} to show within the popup 
+     * notification bar.
+     */
+    public final Node getGraphic() {
+        return graphic.get();
+    }
+    
+    
+    // --- showing
+    private ReadOnlyBooleanWrapper showing = new ReadOnlyBooleanWrapper(this, "showing"); //$NON-NLS-1$
+    
+    /**
+     * A read-only property that represents whether the notification bar popup
+     * should be showing to the user or not. To toggle visibility, use the
+     * {@link #show()} and {@link #hide()} methods.
+     * 
+     * @return A property representing whether the notification bar is currently showing.
+     */
+    public final ReadOnlyBooleanProperty showingProperty() {
+        return showing.getReadOnlyProperty();
+    }
+    private final void setShowing(boolean value) {
+        this.showing.set(value); 
+    }
+    /**
+     * 
+     * @return whether the notification bar is currently showing.
+     */
+    public final boolean isShowing() {
+        return showing.get();
+    }
+    
+    
+    // --- show from top
+    private BooleanProperty showFromTop = new SimpleBooleanProperty(this, "showFromTop", true) { //$NON-NLS-1$
+        @Override protected void invalidated() {
+            updateStyleClasses();
+        }
+    };
+    
+    /**
+     * A property representing whether the notification bar should appear from the
+     * top or the bottom of the NotificationPane area. By default it will appear 
+     * from the top, but this can be changed by setting this property to false.
+     * 
+     * @return A property representing where the notification bar should appear from.
+     */
+    public final BooleanProperty showFromTopProperty() {
+        return showFromTop;
+    }
+    
+    /**
+     * Sets whether the notification bar should appear from the
+     * top or the bottom of the NotificationPane area.
+     * @param value 
+     */
+    public final void setShowFromTop(boolean value) {
+        this.showFromTop.set(value); 
+    }
+    
+    /**
+     * @return whether the notification bar is appearing from the
+     * top or the bottom of the NotificationPane area.
+     */
+    public final boolean isShowFromTop() {
+        return showFromTop.get();
+    }
+    
+    
+    // --- On Showing
+    public final ObjectProperty<EventHandler<Event>> onShowingProperty() { return onShowing; }
+    /**
+     * Called just prior to the {@code NotificationPane} being shown.
+     */
+    public final void setOnShowing(EventHandler<Event> value) { onShowingProperty().set(value); }
+    public final EventHandler<Event> getOnShowing() { return onShowingProperty().get(); }
+    private ObjectProperty<EventHandler<Event>> onShowing = new SimpleObjectProperty<EventHandler<Event>>(this, "onShowing") { //$NON-NLS-1$
+        @Override protected void invalidated() {
+            setEventHandler(ON_SHOWING, get());
+         }
+     };
+
+
+    // -- On Shown
+    public final ObjectProperty<EventHandler<Event>> onShownProperty() { return onShown; }
+    /**
+     * Called just after the {@link NotificationPane} is shown.
+     */
+    public final void setOnShown(EventHandler<Event> value) { onShownProperty().set(value); }
+    public final EventHandler<Event> getOnShown() { return onShownProperty().get(); }
+    private ObjectProperty<EventHandler<Event>> onShown = new SimpleObjectProperty<EventHandler<Event>>(this, "onShown") { //$NON-NLS-1$
+        @Override protected void invalidated() {
+            setEventHandler(ON_SHOWN, get());
+        }
+    };
+
+
+    // --- On Hiding
+    public final ObjectProperty<EventHandler<Event>> onHidingProperty() { return onHiding; }
+    /**
+     * Called just prior to the {@link NotificationPane} being hidden.
+     */
+    public final void setOnHiding(EventHandler<Event> value) { onHidingProperty().set(value); }
+    public final EventHandler<Event> getOnHiding() { return onHidingProperty().get(); }
+    private ObjectProperty<EventHandler<Event>> onHiding = new SimpleObjectProperty<EventHandler<Event>>(this, "onHiding") { //$NON-NLS-1$
+        @Override protected void invalidated() {
+            setEventHandler(ON_HIDING, get());
+        }
+    };
+
+
+    // --- On Hidden
+    public final ObjectProperty<EventHandler<Event>> onHiddenProperty() { return onHidden; }
+    /**
+     * Called just after the {@link NotificationPane} has been hidden.
+     */
+    public final void setOnHidden(EventHandler<Event> value) { onHiddenProperty().set(value); }
+    public final EventHandler<Event> getOnHidden() { return onHiddenProperty().get(); }
+    private ObjectProperty<EventHandler<Event>> onHidden = new SimpleObjectProperty<EventHandler<Event>>(this, "onHidden") { //$NON-NLS-1$
+        @Override protected void invalidated() {
+            setEventHandler(ON_HIDDEN, get());
+        }
+    };
+    
+    // --- close button visibility
+    private BooleanProperty closeButtonVisible = new SimpleBooleanProperty(this, "closeButtonVisible", true); //$NON-NLS-1$
+        
+    /**
+     * A property representing whether the close button in the {@code NotificationPane} should be visible or not.
+     * By default it will appear but this can be changed by setting this property to false.
+     * 
+     * @return A property representing whether the close button in the {@code NotificationPane} should be visible.
+     */
+    public final BooleanProperty closeButtonVisibleProperty() {
+        return closeButtonVisible;
+    }
+    
+    /**
+     * Sets whether the close button in {@code NotificationPane} should be visible.
+     * 
+     * @param value 
+     */
+    public final void setCloseButtonVisible(boolean value) {
+        this.closeButtonVisible.set(value);
+    }
+    
+    /**
+     * @return whether the close button in {@code NotificationPane} is visible.
+     */
+    public final boolean isCloseButtonVisible() {
+        return closeButtonVisible.get();
+    }
+    
+    /***************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    // --- actions
+    private final ObservableList<Action> actions = FXCollections.<Action> observableArrayList();
+
+    /**
+     * Observable list of actions used for the actions area of the notification 
+     * bar. Modifying the contents of this list will change the actions available to
+     * the user.
+     * @return The {@link ObservableList} of actions available to the user.
+     */
+    public final ObservableList<Action> getActions() {
+        return actions;
+    }
+    
+    /**
+     * Call this to make the notification bar appear on top of the 
+     * {@link #contentProperty() content} of this {@link NotificationPane}.
+     * If the notification bar is already showing this will be a no-op.
+     */
+    public void show() {
+        setShowing(true);
+    }
+    
+    /**
+     * Shows the NotificationPane with the 
+     * {@link #contentProperty() content} and {@link #textProperty() text} 
+     * property set, but no {@link #graphicProperty() graphic} property set, and
+     * no {@link #getActions() actions} specified.
+     * 
+     * @param text The text to show in the notification pane.
+     */
+    public void show(final String text) {
+        hideAndThen(new Runnable() {
+            @Override public void run() {
+                setText(text);
+                setShowing(true);
+            }
+        });
+    }
+    
+    /**
+     * Shows the NotificationPane with the 
+     * {@link #contentProperty() content}, {@link #textProperty() text} and 
+     * {@link #graphicProperty() graphic} properties set, but no 
+     * {@link #getActions() actions} specified.
+     * 
+     * @param text The text to show in the notification pane.
+     * @param graphic The node to show in the notification pane.
+     */
+    public void show(final String text, final Node graphic) {
+        hideAndThen(new Runnable() {
+            @Override public void run() {
+                setText(text);
+                setGraphic(graphic);
+                setShowing(true);
+            }
+        });
+    }
+    
+    /**
+     * Shows the NotificationPane with the 
+     * {@link #contentProperty() content}, {@link #textProperty() text} and 
+     * {@link #graphicProperty() graphic} property set, and the provided actions 
+     * copied into the {@link #getActions() actions} list.
+     * 
+     * @param text The text to show in the notification pane.
+     * @param graphic The node to show in the notification pane.
+     * @param actions The actions to show in the notification pane.
+     */
+    public void show(final String text, final Node graphic, final Action... actions) {
+        hideAndThen(new Runnable() {
+            @Override public void run() {
+                setText(text);
+                setGraphic(graphic);
+
+                if (actions == null) {
+                    getActions().clear();
+                } else {
+                    for (Action action : actions) {
+                        if (action == null) continue;
+                        getActions().add(action);
+                    }
+                }
+                
+                setShowing(true);
+            }
+        });
+    }
+    
+    /**
+     * Call this to make the notification bar disappear from the 
+     * {@link #contentProperty() content} of this {@link NotificationPane}.
+     * If the notification bar is already hidden this will be a no-op.
+     */
+    public void hide() {
+        setShowing(false);
+    }
+    
+    
+    
+    /**************************************************************************
+     *                                                                         *
+     * Private Implementation                                                  *
+     *                                                                         *
+     **************************************************************************/
+    
+    private void updateStyleClasses() {
+        getStyleClass().removeAll("top", "bottom"); //$NON-NLS-1$ //$NON-NLS-2$
+        getStyleClass().add(isShowFromTop() ? "top" : "bottom"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    private void hideAndThen(final Runnable r) {
+        if (isShowing()) {
+            final EventHandler<Event> eventHandler = new EventHandler<Event>() {
+                @Override public void handle(Event e) {
+                    r.run();
+                    removeEventHandler(NotificationPane.ON_HIDDEN, this);
+                }
+            };
+            addEventHandler(NotificationPane.ON_HIDDEN, eventHandler);
+            hide();
+        } else {
+            r.run();
+        }
+    }
+    
+    
+    
+    /**************************************************************************
+     *                                                                         *
+     * Stylesheet Handling                                                     *
+     *                                                                         *
+     **************************************************************************/
+     
+     private static final String DEFAULT_STYLE_CLASS = "notification-pane"; //$NON-NLS-1$
+}
diff --git a/src/org/controlsfx/control/Notifications.java b/src/org/controlsfx/control/Notifications.java
new file mode 100644
index 0000000000000000000000000000000000000000..f223db184d8fda10db02915e4a73ec58e2d759c9
--- /dev/null
+++ b/src/org/controlsfx/control/Notifications.java
@@ -0,0 +1,645 @@
+/**
+ * Copyright (c) 2014, 2016, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.NotificationBar;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.ParallelTransition;
+import javafx.animation.Timeline;
+import javafx.animation.Transition;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Pos;
+import javafx.geometry.Rectangle2D;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.image.ImageView;
+import javafx.stage.Popup;
+import javafx.stage.PopupWindow;
+import javafx.stage.Screen;
+import javafx.stage.Window;
+import javafx.util.Duration;
+
+import org.controlsfx.control.action.Action;
+import org.controlsfx.tools.Utils;
+
+/**
+ * An API to show popup notification messages to the user in the corner of their
+ * screen, unlike the {@link NotificationPane} which shows notification messages
+ * within your application itself.
+ * 
+ * <h3>Screenshot</h3>
+ * <p>
+ * The following screenshot shows a sample notification rising from the
+ * bottom-right corner of my screen:
+ * 
+ * <br>
+ * <br>
+ * <img src="notifications.png" alt="Screenshot of Notifications">
+ * 
+ * <h3>Code Example:</h3>
+ * <p>
+ * To create the notification shown in the screenshot, simply do the following:
+ * 
+ * <pre>
+ * {@code
+ * Notifications.create()
+ *              .title("Title Text")
+ *              .text("Hello World 0!")
+ *              .showWarning();
+ * }
+ * </pre>
+ */
+public class Notifications {
+
+    /***************************************************************************
+     * * Static fields * *
+     **************************************************************************/
+
+    private static final String STYLE_CLASS_DARK = "dark"; //$NON-NLS-1$
+
+    /***************************************************************************
+     * * Private fields * *
+     **************************************************************************/
+
+    private String title;
+    private String text;
+    private Node graphic;
+    private ObservableList<Action> actions = FXCollections.observableArrayList();
+    private Pos position = Pos.BOTTOM_RIGHT;
+    private Duration hideAfterDuration = Duration.seconds(5);
+    private boolean hideCloseButton;
+    private EventHandler<ActionEvent> onAction;
+    private Window owner;
+    private Screen screen = Screen.getPrimary();
+
+    private List<String> styleClass = new ArrayList<>();
+
+    /***************************************************************************
+     * * Constructors * *
+     **************************************************************************/
+
+    // we do not allow instantiation of the Notifications class directly - users
+    // must go via the builder API (that is, calling create())
+    private Notifications() {
+        // no-op
+    }
+
+    /***************************************************************************
+     * * Public API * *
+     **************************************************************************/
+
+    /**
+     * Call this to begin the process of building a notification to show.
+     */
+    public static Notifications create() {
+        return new Notifications();
+    }
+
+    /**
+     * Specify the text to show in the notification.
+     */
+    public Notifications text(String text) {
+        this.text = text;
+        return this;
+    }
+
+    /**
+     * Specify the title to show in the notification.
+     */
+    public Notifications title(String title) {
+        this.title = title;
+        return this;
+    }
+
+    /**
+     * Specify the graphic to show in the notification.
+     */
+    public Notifications graphic(Node graphic) {
+        this.graphic = graphic;
+        return this;
+    }
+
+    /**
+     * Specify the position of the notification on screen, by default it is
+     * {@link Pos#BOTTOM_RIGHT bottom-right}.
+     */
+    public Notifications position(Pos position) {
+        this.position = position;
+        return this;
+    }
+
+    /**
+     * The dialog window owner - which can be {@link Screen}, {@link Window}
+     * or {@link Node}. If specified, the notifications will be inside
+     * the owner, otherwise the notifications will be shown within the whole
+     * primary (default) screen.
+     */
+    public Notifications owner(Object owner) {
+        if (owner instanceof Screen) {
+            this.screen = (Screen) owner;
+        } else {
+            this.owner = Utils.getWindow(owner);
+        }
+        return this;
+    }
+
+    /**
+     * Specify the duration that the notification should show, after which it
+     * will be hidden.
+     */
+    public Notifications hideAfter(Duration duration) {
+        this.hideAfterDuration = duration;
+        return this;
+    }
+
+    /**
+     * Specify what to do when the user clicks on the notification (in addition
+     * to the notification hiding, which happens whenever the notification is
+     * clicked on).
+     */
+    public Notifications onAction(EventHandler<ActionEvent> onAction) {
+        this.onAction = onAction;
+        return this;
+    }
+
+    /**
+     * Specify that the notification should use the built-in dark styling,
+     * rather than the default 'modena' notification style (which is a
+     * light-gray).
+     */
+    public Notifications darkStyle() {
+        styleClass.add(STYLE_CLASS_DARK);
+        return this;
+    }
+
+    /**
+     * Specify that the close button in the top-right corner of the notification
+     * should not be shown.
+     */
+    public Notifications hideCloseButton() {
+        this.hideCloseButton = true;
+        return this;
+    }
+
+    /**
+     * Specify the actions that should be shown in the notification as buttons.
+     */
+    public Notifications action(Action... actions) {
+        this.actions = actions == null ? FXCollections.<Action> observableArrayList() : FXCollections
+                .observableArrayList(actions);
+        return this;
+    }
+
+    /**
+     * Instructs the notification to be shown, and that it should use the
+     * built-in 'warning' graphic.
+     */
+    public void showWarning() {
+        graphic(new ImageView(Notifications.class.getResource("/org/controlsfx/dialog/dialog-warning.png").toExternalForm())); //$NON-NLS-1$
+        show();
+    }
+
+    /**
+     * Instructs the notification to be shown, and that it should use the
+     * built-in 'information' graphic.
+     */
+    public void showInformation() {
+        graphic(new ImageView(Notifications.class.getResource("/org/controlsfx/dialog/dialog-information.png").toExternalForm())); //$NON-NLS-1$
+        show();
+    }
+
+    /**
+     * Instructs the notification to be shown, and that it should use the
+     * built-in 'error' graphic.
+     */
+    public void showError() {
+        graphic(new ImageView(Notifications.class.getResource("/org/controlsfx/dialog/dialog-error.png").toExternalForm())); //$NON-NLS-1$
+        show();
+    }
+
+    /**
+     * Instructs the notification to be shown, and that it should use the
+     * built-in 'confirm' graphic.
+     */
+    public void showConfirm() {
+        graphic(new ImageView(Notifications.class.getResource("/org/controlsfx/dialog/dialog-confirm.png").toExternalForm())); //$NON-NLS-1$
+        show();
+    }
+
+    /**
+     * Instructs the notification to be shown.
+     */
+    public void show() {
+        NotificationPopupHandler.getInstance().show(this);
+    }
+
+    /***************************************************************************
+     * * Private support classes * *
+     **************************************************************************/
+
+    // not public so no need for JavaDoc
+    private static final class NotificationPopupHandler {
+
+        private static final NotificationPopupHandler INSTANCE = new NotificationPopupHandler();
+
+        private double startX;
+        private double startY;
+        private double screenWidth;
+        private double screenHeight;
+
+        static final NotificationPopupHandler getInstance() {
+            return INSTANCE;
+        }
+
+        private final Map<Pos, List<Popup>> popupsMap = new HashMap<>();
+        private final double padding = 15;
+
+        // for animating in the notifications
+        private ParallelTransition parallelTransition = new ParallelTransition();
+
+        private boolean isShowing = false;
+
+        public void show(Notifications notification) {
+            Window window;
+            if (notification.owner == null) {
+                /*
+                 * If the owner is not set, we work with the whole screen.
+                 */
+                Rectangle2D screenBounds = notification.screen.getVisualBounds();
+                startX = screenBounds.getMinX();
+                startY = screenBounds.getMinY();
+                screenWidth = screenBounds.getWidth();
+                screenHeight = screenBounds.getHeight();
+
+                window = Utils.getWindow(null);
+            } else {
+                /*
+                 * If the owner is set, we will make the notifications popup
+                 * inside its window.
+                 */
+                startX = notification.owner.getX();
+                startY = notification.owner.getY();
+                screenWidth = notification.owner.getWidth();
+                screenHeight = notification.owner.getHeight();
+                window = notification.owner;
+            }
+            show(window, notification);
+        }
+
+        private void show(Window owner, final Notifications notification) {
+            // Stylesheets which are added to the scene of a popup aren't 
+            // considered for styling. For this reason, we need to find the next 
+            // window in the hierarchy which isn't a popup.  
+            Window ownerWindow = owner;
+            while (ownerWindow instanceof PopupWindow) {
+                ownerWindow = ((PopupWindow) ownerWindow).getOwnerWindow();
+            }
+            // need to install our CSS
+            Scene ownerScene = ownerWindow.getScene();
+            if (ownerScene != null) {
+                String stylesheetUrl = Notifications.class.getResource("notificationpopup.css").toExternalForm(); //$NON-NLS-1$
+                if (!ownerScene.getStylesheets().contains(stylesheetUrl)) {
+                    // The stylesheet needs to be added at the beginning so that
+                    // the styling can be adjusted with custom stylesheets.
+                    ownerScene.getStylesheets().add(0, stylesheetUrl);
+                }
+            }
+
+            final Popup popup = new Popup();
+            popup.setAutoFix(false);
+
+            final Pos p = notification.position;
+
+            final NotificationBar notificationBar = new NotificationBar() {
+                @Override public String getTitle() {
+                    return notification.title;
+                }
+
+                @Override public String getText() {
+                    return notification.text;
+                }
+
+                @Override public Node getGraphic() {
+                    return notification.graphic;
+                }
+
+                @Override public ObservableList<Action> getActions() {
+                    return notification.actions;
+                }
+
+                @Override public boolean isShowing() {
+                    return isShowing;
+                }
+
+                @Override protected double computeMinWidth(double height) {
+                    String text = getText();
+                    Node graphic = getGraphic();
+                    if ((text == null || text.isEmpty()) && (graphic != null)) {
+                        return graphic.minWidth(height);
+                    }
+                    return 400;
+                }
+
+                @Override protected double computeMinHeight(double width) {
+                    String text = getText();
+                    Node graphic = getGraphic();
+                    if ((text == null || text.isEmpty()) && (graphic != null)) {
+                        return graphic.minHeight(width);
+                    }
+                    return 100;
+                }
+
+                @Override public boolean isShowFromTop() {
+                    return NotificationPopupHandler.this.isShowFromTop(notification.position);
+                }
+
+                @Override public void hide() {
+                    isShowing = false;
+
+                    // this would slide the notification bar out of view,
+                    // but I prefer the fade out below
+                    // doHide();
+
+                    // animate out the popup by fading it
+                    createHideTimeline(popup, this, p, Duration.ZERO).play();
+                }
+
+                @Override public boolean isCloseButtonVisible() {
+                    return !notification.hideCloseButton;
+                }
+
+                @Override public double getContainerHeight() {
+                    return startY + screenHeight;
+                }
+
+                @Override public void relocateInParent(double x, double y) {
+                    // this allows for us to slide the notification upwards
+                    switch (p) {
+                    case BOTTOM_LEFT:
+                    case BOTTOM_CENTER:
+                    case BOTTOM_RIGHT:
+                        popup.setAnchorY(y - padding);
+                        break;
+                    default:
+                        // no-op
+                        break;
+                    }
+                }
+            };
+
+            notificationBar.getStyleClass().addAll(notification.styleClass);
+
+            notificationBar.setOnMouseClicked(e -> {
+                if (notification.onAction != null) {
+                    ActionEvent actionEvent = new ActionEvent(notificationBar, notificationBar);
+                    notification.onAction.handle(actionEvent);
+
+                    // animate out the popup
+                    createHideTimeline(popup, notificationBar, p, Duration.ZERO).play();
+                }
+            });
+
+            popup.getContent().add(notificationBar);
+            popup.show(owner, 0, 0);
+
+            // determine location for the popup
+            double anchorX = 0, anchorY = 0;
+            final double barWidth = notificationBar.getWidth();
+            final double barHeight = notificationBar.getHeight();
+
+            // get anchorX
+            switch (p) {
+            case TOP_LEFT:
+            case CENTER_LEFT:
+            case BOTTOM_LEFT:
+                anchorX = padding + startX;
+                break;
+
+            case TOP_CENTER:
+            case CENTER:
+            case BOTTOM_CENTER:
+                anchorX = startX + (screenWidth / 2.0) - barWidth / 2.0 - padding / 2.0;
+                break;
+
+            default:
+            case TOP_RIGHT:
+            case CENTER_RIGHT:
+            case BOTTOM_RIGHT:
+                anchorX = startX + screenWidth - barWidth - padding;
+                break;
+            }
+
+            // get anchorY
+            switch (p) {
+            case TOP_LEFT:
+            case TOP_CENTER:
+            case TOP_RIGHT:
+                anchorY = padding + startY;
+                break;
+
+            case CENTER_LEFT:
+            case CENTER:
+            case CENTER_RIGHT:
+                anchorY = startY + (screenHeight / 2.0) - barHeight / 2.0 - padding / 2.0;
+                break;
+
+            default:
+            case BOTTOM_LEFT:
+            case BOTTOM_CENTER:
+            case BOTTOM_RIGHT:
+                anchorY = startY + screenHeight - barHeight - padding;
+                break;
+            }
+
+            popup.setAnchorX(anchorX);
+            popup.setAnchorY(anchorY);
+
+            isShowing = true;
+            notificationBar.doShow();
+
+            addPopupToMap(p, popup);
+
+            // begin a timeline to get rid of the popup
+            Timeline timeline = createHideTimeline(popup, notificationBar, p, notification.hideAfterDuration);
+            timeline.play();
+        }
+
+        private void hide(Popup popup, Pos p) {
+            popup.hide();
+            removePopupFromMap(p, popup);
+        }
+
+        private Timeline createHideTimeline(final Popup popup, NotificationBar bar, final Pos p, Duration startDelay) {
+            KeyValue fadeOutBegin = new KeyValue(bar.opacityProperty(), 1.0);
+            KeyValue fadeOutEnd = new KeyValue(bar.opacityProperty(), 0.0);
+
+            KeyFrame kfBegin = new KeyFrame(Duration.ZERO, fadeOutBegin);
+            KeyFrame kfEnd = new KeyFrame(Duration.millis(500), fadeOutEnd);
+
+            Timeline timeline = new Timeline(kfBegin, kfEnd);
+            timeline.setDelay(startDelay);
+            timeline.setOnFinished(new EventHandler<ActionEvent>() {
+                @Override
+                public void handle(ActionEvent e) {
+                    hide(popup, p);
+                }
+            });
+
+            return timeline;
+        }
+
+        private void addPopupToMap(Pos p, Popup popup) {
+            List<Popup> popups;
+            if (!popupsMap.containsKey(p)) {
+                popups = new LinkedList<>();
+                popupsMap.put(p, popups);
+            } else {
+                popups = popupsMap.get(p);
+            }
+
+            doAnimation(p, popup);
+
+            // add the popup to the list so it is kept in memory and can be
+            // accessed later on
+            popups.add(popup);
+        }
+
+        private void removePopupFromMap(Pos p, Popup popup) {
+            if (popupsMap.containsKey(p)) {
+                List<Popup> popups = popupsMap.get(p);
+                popups.remove(popup);
+            }
+        }
+
+        private void doAnimation(Pos p, Popup changedPopup) {
+            List<Popup> popups = popupsMap.get(p);
+            if (popups == null) {
+                return;
+            }
+
+            final double newPopupHeight = changedPopup.getContent().get(0).getBoundsInParent().getHeight();
+
+            parallelTransition.stop();
+            parallelTransition.getChildren().clear();
+
+            final boolean isShowFromTop = isShowFromTop(p);
+
+            // animate all other popups in the list upwards so that the new one
+            // is in the 'new' area.
+            // firstly, we need to determine the target positions for all popups
+            double sum = 0;
+            double targetAnchors[] = new double[popups.size()];
+            for (int i = popups.size() - 1; i >= 0; i--) {
+                Popup _popup = popups.get(i);
+
+                final double popupHeight = _popup.getContent().get(0).getBoundsInParent().getHeight();
+
+                if (isShowFromTop) {
+                    if (i == popups.size() - 1) {
+                        sum = startY + newPopupHeight + padding;
+                    } else {
+                        sum += popupHeight;
+                    }
+                    targetAnchors[i] = sum;
+                } else {
+                    if (i == popups.size() - 1) {
+                        sum = changedPopup.getAnchorY() - popupHeight;
+                    } else {
+                        sum -= popupHeight;
+                    }
+
+                    targetAnchors[i] = sum;
+                }
+            }
+
+            // then we set up animations for each popup to animate towards the
+            // target
+            for (int i = popups.size() - 1; i >= 0; i--) {
+                final Popup _popup = popups.get(i);
+                final double anchorYTarget = targetAnchors[i];
+                if(anchorYTarget < 0){
+                    _popup.hide();
+                }
+                final double oldAnchorY = _popup.getAnchorY();
+                final double distance = anchorYTarget - oldAnchorY;
+
+                Transition t = new CustomTransition(_popup, oldAnchorY, distance);
+                t.setCycleCount(1);
+                parallelTransition.getChildren().add(t);
+            }
+            parallelTransition.play();
+        }
+
+        private boolean isShowFromTop(Pos p) {
+            switch (p) {
+            case TOP_LEFT:
+            case TOP_CENTER:
+            case TOP_RIGHT:
+                return true;
+            default:
+                return false;
+            }
+        }
+
+        class CustomTransition extends Transition {
+
+            private WeakReference<Popup> popupWeakReference;
+            private double oldAnchorY;
+            private double distance;
+
+            CustomTransition(Popup popup, double oldAnchorY, double distance) {
+                popupWeakReference = new WeakReference<>(popup);
+                this.oldAnchorY = oldAnchorY;
+                this.distance = distance;
+                setCycleDuration(Duration.millis(350.0));
+            }
+
+            @Override
+            protected void interpolate(double frac) {
+                Popup popup = popupWeakReference.get();
+                if (popup != null) {
+                    double newAnchorY = oldAnchorY + distance * frac;
+                    popup.setAnchorY(newAnchorY);
+                }
+            }
+
+        }
+    }
+}
+
diff --git a/src/org/controlsfx/control/PlusMinusSlider.java b/src/org/controlsfx/control/PlusMinusSlider.java
new file mode 100644
index 0000000000000000000000000000000000000000..8749ffd02aa607b84178007b08ebff41b2d5a53d
--- /dev/null
+++ b/src/org/controlsfx/control/PlusMinusSlider.java
@@ -0,0 +1,345 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.PlusMinusSliderSkin;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ObjectPropertyBase;
+import javafx.beans.property.ReadOnlyDoubleProperty;
+import javafx.beans.property.ReadOnlyDoubleWrapper;
+import javafx.collections.MapChangeListener;
+import javafx.css.CssMetaData;
+import javafx.css.PseudoClass;
+import javafx.css.Styleable;
+import javafx.css.StyleableObjectProperty;
+import javafx.css.StyleableProperty;
+import javafx.event.EventHandler;
+import javafx.event.EventTarget;
+import javafx.event.EventType;
+import javafx.geometry.Orientation;
+import javafx.scene.control.Control;
+import javafx.scene.control.Skin;
+import javafx.scene.input.InputEvent;
+
+import com.sun.javafx.css.converters.EnumConverter;
+
+/**
+ * A plus minus slider allows the user to continously fire an event carrying a
+ * value between -1 and +1 by moving a thumb from its center position to the
+ * left or right (or top and bottom) edge of the control. The thumb will
+ * automatically center itself again on the zero position when the user lets go
+ * of the mouse button. Scrolling through a large list of items at different
+ * speeds is one possible use case for a control like this.
+ * 
+ * <center> <img src="plus-minus-slider.png" alt="Screenshot of PlusMinusSlider"> </center>
+ */
+public class PlusMinusSlider extends ControlsFXControl {
+
+	private static final String DEFAULT_STYLE_CLASS = "plus-minus-slider"; //$NON-NLS-1$
+
+	private static final PseudoClass VERTICAL_PSEUDOCLASS_STATE = PseudoClass
+			.getPseudoClass("vertical"); //$NON-NLS-1$
+
+	private static final PseudoClass HORIZONTAL_PSEUDOCLASS_STATE = PseudoClass
+			.getPseudoClass("horizontal"); //$NON-NLS-1$
+
+	/**
+	 * Constructs a new adjuster control with a default horizontal orientation.
+	 */
+	public PlusMinusSlider() {
+		getStyleClass().add(DEFAULT_STYLE_CLASS);
+
+		setOrientation(Orientation.HORIZONTAL);
+
+		/*
+		 * We are "abusing" the properties map to pass the new value of the
+		 * slider from the skin to the control. It has to be done this way
+		 * because the value property of this control is "read-only".
+		 */
+		getProperties().addListener(new MapChangeListener<Object, Object>() {
+			@Override
+            public void onChanged(MapChangeListener.Change<? extends Object, ? extends Object> change) {
+				if (change.getKey().equals("plusminusslidervalue")) { //$NON-NLS-1$
+					if (change.getValueAdded() != null) {
+						Double valueAdded = (Double) change.getValueAdded();
+						value.set(valueAdded);
+						change.getMap().remove("plusminusslidervalue"); //$NON-NLS-1$
+					}
+				}
+			};
+		});
+	}
+
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(PlusMinusSlider.class, "plusminusslider.css");
+    }
+
+	@Override
+	protected Skin<?> createDefaultSkin() {
+		return new PlusMinusSliderSkin(this);
+	}
+
+	private ReadOnlyDoubleWrapper value = new ReadOnlyDoubleWrapper(this,
+			"value", 0); //$NON-NLS-1$
+
+	/**
+	 * Returns the value property of the adjuster. The value is always between
+	 * -1 and +1.
+	 * 
+	 * @return the value of the adjuster
+	 */
+	public final ReadOnlyDoubleProperty valueProperty() {
+		return value.getReadOnlyProperty();
+	}
+
+	/**
+	 * Returns the value of the value property.
+	 * 
+	 * @return the value of the adjuster [-1, +1]
+	 * 
+	 * @see #valueProperty()
+	 */
+	public final double getValue() {
+		return valueProperty().get();
+	}
+
+	// orientation
+
+	private ObjectProperty<Orientation> orientation;
+
+	/**
+	 * Sets the value of the orientation property.
+	 * 
+	 * @param value
+	 *            the new orientation (horizontal, vertical).
+	 * @see #orientationProperty()
+	 */
+	public final void setOrientation(Orientation value) {
+		orientationProperty().set(value);
+	}
+
+	/**
+	 * Returns the value of the orientation property.
+	 * 
+	 * @return the current orientation of the control
+	 * @see #orientationProperty()
+	 */
+	public final Orientation getOrientation() {
+		return orientation == null ? Orientation.HORIZONTAL : orientation.get();
+	}
+
+	/**
+	 * Returns the stylable object property used for storing the orientation of
+	 * the adjuster control. The CSS property "-fx-orientation" can be used to
+	 * initialize this value.
+	 * 
+	 * @return the orientation property
+	 */
+	public final ObjectProperty<Orientation> orientationProperty() {
+		if (orientation == null) {
+			orientation = new StyleableObjectProperty<Orientation>(null) {
+				@Override
+				protected void invalidated() {
+					final boolean vertical = (get() == Orientation.VERTICAL);
+					pseudoClassStateChanged(VERTICAL_PSEUDOCLASS_STATE,
+							vertical);
+					pseudoClassStateChanged(HORIZONTAL_PSEUDOCLASS_STATE,
+							!vertical);
+				}
+
+				@Override
+				public CssMetaData<PlusMinusSlider, Orientation> getCssMetaData() {
+					return StyleableProperties.ORIENTATION;
+				}
+
+				@Override
+				public Object getBean() {
+					return PlusMinusSlider.this;
+				}
+
+				@Override
+				public String getName() {
+					return "orientation"; //$NON-NLS-1$
+				}
+			};
+		}
+		return orientation;
+	}
+
+	// event support
+
+	/**
+	 * Stores the event handler that will be informed when the adjuster's value
+	 * changes.
+	 * 
+	 * @return the value change event handler property
+	 */
+	public final ObjectProperty<EventHandler<PlusMinusEvent>> onValueChangedProperty() {
+		return onValueChanged;
+	}
+
+	/**
+	 * Sets an event handler that will receive plus minus events when the user
+	 * moves the adjuster's thumb.
+	 * 
+	 * @param value
+	 *            the event handler
+	 * 
+	 * @see #onValueChangedProperty()
+	 */
+	public final void setOnValueChanged(EventHandler<PlusMinusEvent> value) {
+		onValueChangedProperty().set(value);
+	}
+
+	/**
+	 * Returns the event handler that will be notified when the adjuster's value
+	 * changes.
+	 * 
+	 * @return An EventHandler.
+	 */
+	public final EventHandler<PlusMinusEvent> getOnValueChanged() {
+		return onValueChangedProperty().get();
+	}
+
+	private ObjectProperty<EventHandler<PlusMinusEvent>> onValueChanged = new ObjectPropertyBase<EventHandler<PlusMinusEvent>>() {
+
+		@Override
+		protected void invalidated() {
+			setEventHandler(PlusMinusEvent.VALUE_CHANGED, get());
+		}
+
+		@Override
+		public Object getBean() {
+			return PlusMinusSlider.this;
+		}
+
+		@Override
+		public String getName() {
+			return "onValueChanged"; //$NON-NLS-1$
+		}
+	};
+
+	private static class StyleableProperties {
+
+		private static final CssMetaData<PlusMinusSlider, Orientation> ORIENTATION = new CssMetaData<PlusMinusSlider, Orientation>(
+				"-fx-orientation", new EnumConverter<>( //$NON-NLS-1$
+						Orientation.class), Orientation.VERTICAL) {
+
+			@Override
+			public Orientation getInitialValue(PlusMinusSlider node) {
+				// A vertical Slider should remain vertical
+				return node.getOrientation();
+			}
+
+			@Override
+			public boolean isSettable(PlusMinusSlider n) {
+				return n.orientation == null || !n.orientation.isBound();
+			}
+
+			@SuppressWarnings("unchecked")
+			@Override
+			public StyleableProperty<Orientation> getStyleableProperty(
+					PlusMinusSlider n) {
+				return (StyleableProperty<Orientation>) n.orientationProperty();
+			}
+		};
+
+		private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
+		static {
+			final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData());
+			styleables.add(ORIENTATION);
+
+			STYLEABLES = Collections.unmodifiableList(styleables);
+		}
+	}
+
+	/**
+	 * @return The CssMetaData associated with this class, which may include the
+	 *         CssMetaData of its super classes.
+	 * @since JavaFX 8.0
+	 */
+	public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
+		return StyleableProperties.STYLEABLES;
+	}
+
+	/**
+	 * An event class used by the {@link PlusMinusSlider} to inform event
+	 * handlers about changes.
+	 */
+	public static class PlusMinusEvent extends InputEvent {
+
+		private static final long serialVersionUID = 2881004583512990781L;
+
+		public static final EventType<PlusMinusEvent> ANY = new EventType<>(
+				InputEvent.ANY, "ANY"); //$NON-NLS-1$
+
+		/**
+		 * An event type used when the value property (
+		 * {@link PlusMinusSlider#valueProperty()}) changes.
+		 */
+		public static final EventType<PlusMinusEvent> VALUE_CHANGED = new EventType<>(
+				PlusMinusEvent.ANY, "VALUE_CHANGED"); //$NON-NLS-1$
+
+		private double value;
+
+		/**
+		 * Constructs a new event object.
+		 * 
+		 * @param source
+		 *            the source of the event (always the
+		 *            {@link PlusMinusSlider})
+		 * @param target
+		 *            the target of the event (always the
+		 *            {@link PlusMinusSlider})
+		 * @param eventType
+		 *            the type of the event (e.g. {@link #VALUE_CHANGED})
+		 * @param value
+		 *            the actual current value of the adjuster
+		 */
+		public PlusMinusEvent(Object source, EventTarget target,
+				EventType<? extends InputEvent> eventType, double value) {
+			super(source, target, eventType);
+
+			this.value = value;
+		}
+
+		/**
+		 * The value of the {@link PlusMinusSlider}.
+		 * 
+		 * @return the value
+		 */
+		public double getValue() {
+			return value;
+		}
+	}
+}
diff --git a/src/org/controlsfx/control/PopOver.java b/src/org/controlsfx/control/PopOver.java
new file mode 100644
index 0000000000000000000000000000000000000000..b98b4e54c6a423197310c0a81dca9cb2b263386c
--- /dev/null
+++ b/src/org/controlsfx/control/PopOver.java
@@ -0,0 +1,1011 @@
+/**
+ * Copyright (c) 2013, 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.PopOverSkin;
+import javafx.animation.FadeTransition;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.WeakInvalidationListener;
+import javafx.beans.property.*;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.beans.value.WeakChangeListener;
+import javafx.event.EventHandler;
+import javafx.event.WeakEventHandler;
+import javafx.geometry.Bounds;
+import javafx.geometry.Insets;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.control.PopupControl;
+import javafx.scene.control.Skin;
+import javafx.scene.layout.StackPane;
+import javafx.stage.Window;
+import javafx.stage.WindowEvent;
+import javafx.util.Duration;
+
+import static impl.org.controlsfx.i18n.Localization.asKey;
+import static impl.org.controlsfx.i18n.Localization.localize;
+import static java.util.Objects.requireNonNull;
+import static javafx.scene.input.MouseEvent.MOUSE_CLICKED;
+
+/**
+ * The PopOver control provides detailed information about an owning node in a
+ * popup window. The popup window has a very lightweight appearance (no default
+ * window decorations) and an arrow pointing at the owner. Due to the nature of
+ * popup windows the PopOver will move around with the parent window when the
+ * user drags it. <br>
+ * <center> <img src="popover.png" alt="Screenshot of PopOver"> </center> <br>
+ * The PopOver can be detached from the owning node by dragging it away from the
+ * owner. It stops displaying an arrow and starts displaying a title and a close
+ * icon. <br>
+ * <br>
+ * <center> <img src="popover-detached.png"
+ * alt="Screenshot of a detached PopOver"> </center> <br>
+ * The following image shows a popover with an accordion content node. PopOver
+ * controls are automatically resizing themselves when the content node changes
+ * its size.<br>
+ * <br>
+ * <center> <img src="popover-accordion.png"
+ * alt="Screenshot of PopOver containing an Accordion"> </center> <br>
+ * For styling apply stylesheets to the root pane of the PopOver.
+ *
+ * <h3>Example:</h3>
+ *
+ * <pre>
+ * PopOver popOver = new PopOver();
+ * popOver.getRoot().getStylesheets().add(...);
+ * </pre>
+ *
+ */
+public class PopOver extends PopupControl {
+
+    private static final String DEFAULT_STYLE_CLASS = "popover"; //$NON-NLS-1$
+
+    private static final Duration DEFAULT_FADE_DURATION = Duration.seconds(.2);
+
+    private double targetX;
+
+    private double targetY;
+
+    private final SimpleBooleanProperty animated = new SimpleBooleanProperty(true);
+    private final ObjectProperty<Duration> fadeInDuration = new SimpleObjectProperty<>(DEFAULT_FADE_DURATION);
+    private final ObjectProperty<Duration> fadeOutDuration = new SimpleObjectProperty<>(DEFAULT_FADE_DURATION);
+
+    /**
+     * Creates a pop over with a label as the content node.
+     */
+    public PopOver() {
+        super();
+
+        getStyleClass().add(DEFAULT_STYLE_CLASS);
+
+        getRoot().getStylesheets().add(
+                PopOver.class.getResource("popover.css").toExternalForm()); //$NON-NLS-1$
+
+        setAnchorLocation(AnchorLocation.WINDOW_TOP_LEFT);
+        setOnHiding(new EventHandler<WindowEvent>() {
+            @Override
+            public void handle(WindowEvent evt) {
+                setDetached(false);
+            }
+        });
+
+        /*
+         * Create some initial content.
+         */
+        Label label = new Label(localize(asKey("popOver.default.content"))); //$NON-NLS-1$
+        label.setPrefSize(200, 200);
+        label.setPadding(new Insets(4));
+        setContentNode(label);
+
+        InvalidationListener repositionListener = observable -> {
+            if (isShowing() && !isDetached()) {
+                show(getOwnerNode(), targetX, targetY);
+                adjustWindowLocation();
+            }
+        };
+
+        arrowSize.addListener(repositionListener);
+        cornerRadius.addListener(repositionListener);
+        arrowLocation.addListener(repositionListener);
+        arrowIndent.addListener(repositionListener);
+        headerAlwaysVisible.addListener(repositionListener);
+
+        /*
+         * A detached popover should of course not automatically hide itself.
+         */
+        detached.addListener(it -> {
+            if (isDetached()) {
+                setAutoHide(false);
+            } else {
+                setAutoHide(true);
+            }
+        });
+
+        setAutoHide(true);
+    }
+
+    /**
+     * Creates a pop over with the given node as the content node.
+     *
+     * @param content
+     *            The content shown by the pop over
+     */
+    public PopOver(Node content) {
+        this();
+
+        setContentNode(content);
+    }
+
+    @Override
+    protected Skin<?> createDefaultSkin() {
+        return new PopOverSkin(this);
+    }
+
+    private final StackPane root = new StackPane();
+
+    /**
+     * The root pane stores the content node of the popover. It is accessible
+     * via this method in order to support proper styling.
+     *
+     * <h3>Example:</h3>
+     *
+     * <pre>
+     * PopOver popOver = new PopOver();
+     * popOver.getRoot().getStylesheets().add(...);
+     * </pre>
+     *
+     * @return the root pane
+     */
+    public final StackPane getRoot() {
+        return root;
+    }
+
+    // Content support.
+
+    private final ObjectProperty<Node> contentNode = new SimpleObjectProperty<Node>(
+            this, "contentNode") { //$NON-NLS-1$
+        @Override
+        public void setValue(Node node) {
+            if (node == null) {
+                throw new IllegalArgumentException(
+                        "content node can not be null"); //$NON-NLS-1$
+            }
+        };
+    };
+
+    /**
+     * Returns the content shown by the pop over.
+     *
+     * @return the content node property
+     */
+    public final ObjectProperty<Node> contentNodeProperty() {
+        return contentNode;
+    }
+
+    /**
+     * Returns the value of the content property
+     *
+     * @return the content node
+     *
+     * @see #contentNodeProperty()
+     */
+    public final Node getContentNode() {
+        return contentNodeProperty().get();
+    }
+
+    /**
+     * Sets the value of the content property.
+     *
+     * @param content
+     *            the new content node value
+     *
+     * @see #contentNodeProperty()
+     */
+    public final void setContentNode(Node content) {
+        contentNodeProperty().set(content);
+    }
+
+    private InvalidationListener hideListener = new InvalidationListener() {
+        @Override
+        public void invalidated(Observable observable) {
+            if (!isDetached()) {
+                hide(Duration.ZERO);
+            }
+        }
+    };
+
+    private WeakInvalidationListener weakHideListener = new WeakInvalidationListener(
+            hideListener);
+
+    private ChangeListener<Number> xListener = new ChangeListener<Number>() {
+        @Override
+        public void changed(ObservableValue<? extends Number> value,
+                Number oldX, Number newX) {
+            if (!isDetached()) {
+                setAnchorX(getAnchorX() + (newX.doubleValue() - oldX.doubleValue()));
+            }
+        }
+    };
+
+    private WeakChangeListener<Number> weakXListener = new WeakChangeListener<>(
+            xListener);
+
+    private ChangeListener<Number> yListener = new ChangeListener<Number>() {
+        @Override
+        public void changed(ObservableValue<? extends Number> value,
+                Number oldY, Number newY) {
+            if (!isDetached()) {
+                setAnchorY(getAnchorY() + (newY.doubleValue() - oldY.doubleValue()));
+            }
+        }
+    };
+
+    private WeakChangeListener<Number> weakYListener = new WeakChangeListener<>(
+            yListener);
+
+    private Window ownerWindow;
+    private final EventHandler<WindowEvent> closePopOverOnOwnerWindowCloseLambda = event -> ownerWindowClosing();
+    private final WeakEventHandler<WindowEvent> closePopOverOnOwnerWindowClose = new WeakEventHandler<>(closePopOverOnOwnerWindowCloseLambda);
+
+    /**
+     * Shows the pop over in a position relative to the edges of the given owner
+     * node. The position is dependent on the arrow location. If the arrow is
+     * pointing to the right then the pop over will be placed to the left of the
+     * given owner. If the arrow points up then the pop over will be placed
+     * below the given owner node. The arrow will slightly overlap with the
+     * owner node.
+     *
+     * @param owner
+     *            the owner of the pop over
+     */
+    public final void show(Node owner) {
+        show(owner, 4);
+    }
+
+    /**
+     * Shows the pop over in a position relative to the edges of the given owner
+     * node. The position is dependent on the arrow location. If the arrow is
+     * pointing to the right then the pop over will be placed to the left of the
+     * given owner. If the arrow points up then the pop over will be placed
+     * below the given owner node.
+     *
+     * @param owner
+     *            the owner of the pop over
+     * @param offset
+     *            if negative specifies the distance to the owner node or when
+     *            positive specifies the number of pixels that the arrow will
+     *            overlap with the owner node (positive values are recommended)
+     */
+    public final void show(Node owner, double offset) {
+        requireNonNull(owner);
+
+        Bounds bounds = owner.localToScreen(owner.getBoundsInLocal());
+
+        switch (getArrowLocation()) {
+        case BOTTOM_CENTER:
+        case BOTTOM_LEFT:
+        case BOTTOM_RIGHT:
+            show(owner, bounds.getMinX() + bounds.getWidth() / 2,
+                    bounds.getMinY() + offset);
+            break;
+        case LEFT_BOTTOM:
+        case LEFT_CENTER:
+        case LEFT_TOP:
+            show(owner, bounds.getMaxX() - offset,
+                    bounds.getMinY() + bounds.getHeight() / 2);
+            break;
+        case RIGHT_BOTTOM:
+        case RIGHT_CENTER:
+        case RIGHT_TOP:
+            show(owner, bounds.getMinX() + offset,
+                    bounds.getMinY() + bounds.getHeight() / 2);
+            break;
+        case TOP_CENTER:
+        case TOP_LEFT:
+        case TOP_RIGHT:
+            show(owner, bounds.getMinX() + bounds.getWidth() / 2,
+                    bounds.getMinY() + bounds.getHeight() - offset);
+            break;
+        default:
+            break;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void show(Window owner) {
+        super.show(owner);
+        ownerWindow = owner;
+
+        if (isAnimated()) {
+            showFadeInAnimation(getFadeInDuration());
+        }
+
+        ownerWindow.addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST,
+                closePopOverOnOwnerWindowClose);
+        ownerWindow.addEventFilter(WindowEvent.WINDOW_HIDING,
+                closePopOverOnOwnerWindowClose);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void show(Window ownerWindow, double anchorX, double anchorY) {
+        super.show(ownerWindow, anchorX, anchorY);
+        this.ownerWindow = ownerWindow;
+
+        if (isAnimated()) {
+            showFadeInAnimation(getFadeInDuration());
+        }
+
+        ownerWindow.addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST,
+                closePopOverOnOwnerWindowClose);
+        ownerWindow.addEventFilter(WindowEvent.WINDOW_HIDING,
+                closePopOverOnOwnerWindowClose);
+    }
+
+    /**
+     * Makes the pop over visible at the give location and associates it with
+     * the given owner node. The x and y coordinate will be the target location
+     * of the arrow of the pop over and not the location of the window.
+     *
+     * @param owner
+     *            the owning node
+     * @param x
+     *            the x coordinate for the pop over arrow tip
+     * @param y
+     *            the y coordinate for the pop over arrow tip
+     */
+    @Override
+    public final void show(Node owner, double x, double y) {
+        show(owner, x, y, getFadeInDuration());
+    }
+
+    /**
+     * Makes the pop over visible at the give location and associates it with
+     * the given owner node. The x and y coordinate will be the target location
+     * of the arrow of the pop over and not the location of the window.
+     *
+     * @param owner
+     *            the owning node
+     * @param x
+     *            the x coordinate for the pop over arrow tip
+     * @param y
+     *            the y coordinate for the pop over arrow tip
+     * @param fadeInDuration
+     *            the time it takes for the pop over to be fully visible. This duration takes precedence over the fade-in property without setting.
+     */
+    public final void show(Node owner, double x, double y,
+            Duration fadeInDuration) {
+
+        /*
+         * Calling show() a second time without first closing the pop over
+         * causes it to be placed at the wrong location.
+         */
+        if (ownerWindow != null && isShowing()) {
+            super.hide();
+        }
+
+        targetX = x;
+        targetY = y;
+
+        if (owner == null) {
+            throw new IllegalArgumentException("owner can not be null"); //$NON-NLS-1$
+        }
+
+        if (fadeInDuration == null) {
+            fadeInDuration = DEFAULT_FADE_DURATION;
+        }
+
+        /*
+         * This is all needed because children windows do not get their x and y
+         * coordinate updated when the owning window gets moved by the user.
+         */
+        if (ownerWindow != null) {
+            ownerWindow.xProperty().removeListener(weakXListener);
+            ownerWindow.yProperty().removeListener(weakYListener);
+            ownerWindow.widthProperty().removeListener(weakHideListener);
+            ownerWindow.heightProperty().removeListener(weakHideListener);
+        }
+
+        ownerWindow = owner.getScene().getWindow();
+        ownerWindow.xProperty().addListener(weakXListener);
+        ownerWindow.yProperty().addListener(weakYListener);
+        ownerWindow.widthProperty().addListener(weakHideListener);
+        ownerWindow.heightProperty().addListener(weakHideListener);
+
+        setOnShown(evt -> {
+
+            /*
+             * The user clicked somewhere into the transparent background. If
+             * this is the case then hide the window (when attached).
+             */
+            getScene().addEventHandler(MOUSE_CLICKED, mouseEvent -> {
+                if (mouseEvent.getTarget().equals(getScene().getRoot())) {
+                    if (!isDetached()) {
+                        hide();
+                    }
+                }
+            });
+
+            /*
+             * Move the window so that the arrow will end up pointing at the
+             * target coordinates.
+             */
+            adjustWindowLocation();
+        });
+
+        super.show(owner, x, y);
+
+        if (isAnimated()) {
+            showFadeInAnimation(fadeInDuration);
+        }
+
+        // Bug fix - close popup when owner window is closing
+        ownerWindow.addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST,
+                closePopOverOnOwnerWindowClose);
+        ownerWindow.addEventFilter(WindowEvent.WINDOW_HIDING,
+                closePopOverOnOwnerWindowClose);
+    }
+
+    private void showFadeInAnimation(Duration fadeInDuration) {
+        // Fade In
+        Node skinNode = getSkin().getNode();
+        skinNode.setOpacity(0);
+
+        FadeTransition fadeIn = new FadeTransition(fadeInDuration, skinNode);
+        fadeIn.setFromValue(0);
+        fadeIn.setToValue(1);
+        fadeIn.play();
+    }
+
+    private void ownerWindowClosing() {
+        hide(Duration.ZERO);
+    }
+
+    /**
+     * Hides the pop over by quickly changing its opacity to 0.
+     *
+     * @see #hide(Duration)
+     */
+    @Override
+    public final void hide() {
+        hide(getFadeOutDuration());
+    }
+
+    /**
+     * Hides the pop over by quickly changing its opacity to 0.
+     *
+     * @param fadeOutDuration
+     *            the duration of the fade transition that is being used to
+     *            change the opacity of the pop over
+     * @since 1.0
+     */
+    public final void hide(Duration fadeOutDuration) {
+        //We must remove EventFilter in order to prevent memory leak.
+        if (ownerWindow != null){
+            ownerWindow.removeEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST,
+                    closePopOverOnOwnerWindowClose);
+            ownerWindow.removeEventFilter(WindowEvent.WINDOW_HIDING,
+                closePopOverOnOwnerWindowClose);
+        }
+        if (fadeOutDuration == null) {
+            fadeOutDuration = DEFAULT_FADE_DURATION;
+        }
+
+        if (isShowing()) {
+            if (isAnimated()) {
+                // Fade Out
+                Node skinNode = getSkin().getNode();
+
+                FadeTransition fadeOut = new FadeTransition(fadeOutDuration,
+                        skinNode);
+                fadeOut.setFromValue(skinNode.getOpacity());
+                fadeOut.setToValue(0);
+                fadeOut.setOnFinished(evt -> super.hide());
+                fadeOut.play();
+            } else {
+                super.hide();
+            }
+        }
+    }
+
+    private void adjustWindowLocation() {
+        Bounds bounds = PopOver.this.getSkin().getNode().getBoundsInParent();
+
+        switch (getArrowLocation()) {
+        case TOP_CENTER:
+        case TOP_LEFT:
+        case TOP_RIGHT:
+            setAnchorX(getAnchorX() + bounds.getMinX() - computeXOffset());
+            setAnchorY(getAnchorY() + bounds.getMinY() + getArrowSize());
+            break;
+        case LEFT_TOP:
+        case LEFT_CENTER:
+        case LEFT_BOTTOM:
+            setAnchorX(getAnchorX() + bounds.getMinX() + getArrowSize());
+            setAnchorY(getAnchorY() + bounds.getMinY() - computeYOffset());
+            break;
+        case BOTTOM_CENTER:
+        case BOTTOM_LEFT:
+        case BOTTOM_RIGHT:
+            setAnchorX(getAnchorX() + bounds.getMinX() - computeXOffset());
+            setAnchorY(getAnchorY() - bounds.getMinY() - bounds.getMaxY() - 1);
+            break;
+        case RIGHT_TOP:
+        case RIGHT_BOTTOM:
+        case RIGHT_CENTER:
+            setAnchorX(getAnchorX() - bounds.getMinX() - bounds.getMaxX() - 1);
+            setAnchorY(getAnchorY() + bounds.getMinY() - computeYOffset());
+            break;
+        }
+    }
+
+    private double computeXOffset() {
+        switch (getArrowLocation()) {
+        case TOP_LEFT:
+        case BOTTOM_LEFT:
+            return getCornerRadius() + getArrowIndent() + getArrowSize();
+        case TOP_CENTER:
+        case BOTTOM_CENTER:
+            return getContentNode().prefWidth(-1) / 2;
+        case TOP_RIGHT:
+        case BOTTOM_RIGHT:
+            return getContentNode().prefWidth(-1) - getArrowIndent()
+                    - getCornerRadius() - getArrowSize();
+        default:
+            return 0;
+        }
+    }
+
+    private double computeYOffset() {
+        double prefContentHeight = getContentNode().prefHeight(-1);
+
+        switch (getArrowLocation()) {
+        case LEFT_TOP:
+        case RIGHT_TOP:
+            return getCornerRadius() + getArrowIndent() + getArrowSize();
+        case LEFT_CENTER:
+        case RIGHT_CENTER:
+            return Math.max(prefContentHeight, 2 * (getCornerRadius()
+                    + getArrowIndent() + getArrowSize())) / 2;
+        case LEFT_BOTTOM:
+        case RIGHT_BOTTOM:
+            return Math.max(prefContentHeight - getCornerRadius()
+                    - getArrowIndent() - getArrowSize(), getCornerRadius()
+                    + getArrowIndent() + getArrowSize());
+        default:
+            return 0;
+        }
+    }
+
+    /**
+     * Detaches the pop over from the owning node. The pop over will no longer
+     * display an arrow pointing at the owner node.
+     */
+    public final void detach() {
+        if (isDetachable()) {
+            setDetached(true);
+        }
+    }
+
+    // always show header
+
+    private final BooleanProperty headerAlwaysVisible = new SimpleBooleanProperty(this, "headerAlwaysVisible"); //$NON-NLS-1$
+
+    /**
+     * Determines whether or not the {@link PopOver} header should remain visible, even while attached.
+     */
+    public final BooleanProperty headerAlwaysVisibleProperty() {
+        return headerAlwaysVisible;
+    }
+
+    /**
+     * Sets the value of the headerAlwaysVisible property.
+     *
+     * @param visible
+     *            if true, then the header is visible even while attached
+     *
+     * @see #headerAlwaysVisibleProperty()
+     */
+    public final void setHeaderAlwaysVisible(boolean visible) {
+        headerAlwaysVisible.setValue(visible);
+    }
+
+    /**
+     * Returns the value of the detachable property.
+     *
+     * @return true if the header is visible even while attached
+     *
+     * @see #headerAlwaysVisibleProperty()
+     */
+    public final boolean isHeaderAlwaysVisible() {
+        return headerAlwaysVisible.getValue();
+    }
+
+
+    // detach support
+
+    private final BooleanProperty detachable = new SimpleBooleanProperty(this,
+            "detachable", true); //$NON-NLS-1$
+
+    /**
+     * Determines if the pop over is detachable at all.
+     */
+    public final BooleanProperty detachableProperty() {
+        return detachable;
+    }
+
+    /**
+     * Sets the value of the detachable property.
+     *
+     * @param detachable
+     *            if true then the user can detach / tear off the pop over
+     *
+     * @see #detachableProperty()
+     */
+    public final void setDetachable(boolean detachable) {
+        detachableProperty().set(detachable);
+    }
+
+    /**
+     * Returns the value of the detachable property.
+     *
+     * @return true if the user is allowed to detach / tear off the pop over
+     *
+     * @see #detachableProperty()
+     */
+    public final boolean isDetachable() {
+        return detachableProperty().get();
+    }
+
+    private final BooleanProperty detached = new SimpleBooleanProperty(this,
+            "detached", false); //$NON-NLS-1$
+
+    /**
+     * Determines whether the pop over is detached from the owning node or not.
+     * A detached pop over no longer shows an arrow pointing at the owner and
+     * features its own title bar.
+     *
+     * @return the detached property
+     */
+    public final BooleanProperty detachedProperty() {
+        return detached;
+    }
+
+    /**
+     * Sets the value of the detached property.
+     *
+     * @param detached
+     *            if true the pop over will change its apperance to "detached"
+     *            mode
+     *
+     * @see #detachedProperty()
+     */
+    public final void setDetached(boolean detached) {
+        detachedProperty().set(detached);
+    }
+
+    /**
+     * Returns the value of the detached property.
+     *
+     * @return true if the pop over is currently detached.
+     *
+     * @see #detachedProperty()
+     */
+    public final boolean isDetached() {
+        return detachedProperty().get();
+    }
+
+    // arrow size support
+
+    // TODO: make styleable
+
+    private final DoubleProperty arrowSize = new SimpleDoubleProperty(this,
+            "arrowSize", 12); //$NON-NLS-1$
+
+    /**
+     * Controls the size of the arrow. Default value is 12.
+     *
+     * @return the arrow size property
+     */
+    public final DoubleProperty arrowSizeProperty() {
+        return arrowSize;
+    }
+
+    /**
+     * Returns the value of the arrow size property.
+     *
+     * @return the arrow size property value
+     *
+     * @see #arrowSizeProperty()
+     */
+    public final double getArrowSize() {
+        return arrowSizeProperty().get();
+    }
+
+    /**
+     * Sets the value of the arrow size property.
+     *
+     * @param size
+     *            the new value of the arrow size property
+     *
+     * @see #arrowSizeProperty()
+     */
+    public final void setArrowSize(double size) {
+        arrowSizeProperty().set(size);
+    }
+
+    // arrow indent support
+
+    // TODO: make styleable
+
+    private final DoubleProperty arrowIndent = new SimpleDoubleProperty(this,
+            "arrowIndent", 12); //$NON-NLS-1$
+
+    /**
+     * Controls the distance between the arrow and the corners of the pop over.
+     * The default value is 12.
+     *
+     * @return the arrow indent property
+     */
+    public final DoubleProperty arrowIndentProperty() {
+        return arrowIndent;
+    }
+
+    /**
+     * Returns the value of the arrow indent property.
+     *
+     * @return the arrow indent value
+     *
+     * @see #arrowIndentProperty()
+     */
+    public final double getArrowIndent() {
+        return arrowIndentProperty().get();
+    }
+
+    /**
+     * Sets the value of the arrow indent property.
+     *
+     * @param size
+     *            the arrow indent value
+     *
+     * @see #arrowIndentProperty()
+     */
+    public final void setArrowIndent(double size) {
+        arrowIndentProperty().set(size);
+    }
+
+    // radius support
+
+    // TODO: make styleable
+
+    private final DoubleProperty cornerRadius = new SimpleDoubleProperty(this,
+            "cornerRadius", 6); //$NON-NLS-1$
+
+    /**
+     * Returns the corner radius property for the pop over.
+     *
+     * @return the corner radius property (default is 6)
+     */
+    public final DoubleProperty cornerRadiusProperty() {
+        return cornerRadius;
+    }
+
+    /**
+     * Returns the value of the corner radius property.
+     *
+     * @return the corner radius
+     *
+     * @see #cornerRadiusProperty()
+     */
+    public final double getCornerRadius() {
+        return cornerRadiusProperty().get();
+    }
+
+    /**
+     * Sets the value of the corner radius property.
+     *
+     * @param radius
+     *            the corner radius
+     *
+     * @see #cornerRadiusProperty()
+     */
+    public final void setCornerRadius(double radius) {
+        cornerRadiusProperty().set(radius);
+    }
+
+    // Detached stage title
+
+    private final StringProperty title = new SimpleStringProperty(this, "title", localize(asKey("popOver.default.title"))); //$NON-NLS-1$ //$NON-NLS-2$
+
+    /**
+     * Stores the title to display in the PopOver's header.
+     *
+     * @return the title property
+     */
+    public final StringProperty titleProperty() {
+        return title;
+    }
+
+    /**
+     * Returns the value of the title property.
+     *
+     * @return the detached title
+     * @see #titleProperty()
+     */
+    public final String getTitle() {
+        return titleProperty().get();
+    }
+
+    /**
+     * Sets the value of the title property.
+     *
+     * @param title the title to use when detached
+     * @see #titleProperty()
+     */
+    public final void setTitle(String title) {
+        if (title == null) {
+            throw new IllegalArgumentException("title can not be null"); //$NON-NLS-1$
+        }
+
+        titleProperty().set(title);
+    }
+
+    private final ObjectProperty<ArrowLocation> arrowLocation = new SimpleObjectProperty<>(
+            this, "arrowLocation", ArrowLocation.LEFT_TOP); //$NON-NLS-1$
+
+    /**
+     * Stores the preferred arrow location. This might not be the actual
+     * location of the arrow if auto fix is enabled.
+     *
+     * @see #setAutoFix(boolean)
+     *
+     * @return the arrow location property
+     */
+    public final ObjectProperty<ArrowLocation> arrowLocationProperty() {
+        return arrowLocation;
+    }
+
+    /**
+     * Sets the value of the arrow location property.
+     *
+     * @see #arrowLocationProperty()
+     *
+     * @param location
+     *            the requested location
+     */
+    public final void setArrowLocation(ArrowLocation location) {
+        arrowLocationProperty().set(location);
+    }
+
+    /**
+     * Returns the value of the arrow location property.
+     *
+     * @see #arrowLocationProperty()
+     *
+     * @return the preferred arrow location
+     */
+    public final ArrowLocation getArrowLocation() {
+        return arrowLocationProperty().get();
+    }
+
+    /**
+     * All possible arrow locations.
+     */
+    public enum ArrowLocation {
+        LEFT_TOP, LEFT_CENTER, LEFT_BOTTOM, RIGHT_TOP, RIGHT_CENTER, RIGHT_BOTTOM, TOP_LEFT, TOP_CENTER, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT;
+    }
+
+    /**
+     * Stores the fade-in duration. This should be set before calling PopOver.show(..).
+     *
+     * @return the fade-in duration property
+     */
+    public final ObjectProperty<Duration> fadeInDurationProperty() {
+        return fadeInDuration;
+    }
+
+    /**
+     * Stores the fade-out duration.
+     *
+     * @return the fade-out duration property
+     */
+    public final ObjectProperty<Duration> fadeOutDurationProperty() {
+        return fadeOutDuration;
+    }
+
+    /**
+     * Returns the value of the fade-in duration property.
+     *
+     * @return the fade-in duration
+     * @see #fadeInDurationProperty()
+     */
+    public final Duration getFadeInDuration() {
+        return fadeInDurationProperty().get();
+    }
+
+    /**
+     * Sets the value of the fade-in duration property. This should be set before calling PopOver.show(..).
+     *
+     * @param duration the requested fade-in duration
+     * @see #fadeInDurationProperty()
+     */
+    public final void setFadeInDuration(Duration duration) {
+        fadeInDurationProperty().setValue(duration);
+    }
+
+    /**
+     * Returns the value of the fade-out duration property.
+     *
+     * @return the fade-out duration
+     * @see #fadeOutDurationProperty()
+     */
+    public final Duration getFadeOutDuration() {
+        return fadeOutDurationProperty().get();
+    }
+
+    /**
+     * Sets the value of the fade-out duration property.
+     *
+     * @param duration the requested fade-out duration
+     * @see #fadeOutDurationProperty()
+     */
+    public final void setFadeOutDuration(Duration duration) {
+        fadeOutDurationProperty().setValue(duration);
+    }
+
+    /**
+     * Stores the "animated" flag. If true then the PopOver will be shown / hidden with a short fade in / out animation.
+     *
+     * @return the "animated" property
+     */
+    public final BooleanProperty animatedProperty() {
+        return animated;
+    }
+
+    /**
+     * Returns the value of the "animated" property.
+     *
+     * @return true if the PopOver will be shown and hidden with a short fade animation
+     * @see #animatedProperty()
+     */
+    public final boolean isAnimated() {
+        return animatedProperty().get();
+    }
+
+    /**
+     * Sets the value of the "animated" property.
+     *
+     * @param animated if true the PopOver will be shown and hidden with a short fade animation
+     * @see #animatedProperty()
+     */
+    public final void setAnimated(boolean animated) {
+        animatedProperty().set(animated);
+    }
+}
diff --git a/src/org/controlsfx/control/PrefixSelectionChoiceBox.java b/src/org/controlsfx/control/PrefixSelectionChoiceBox.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5cf6ce143dc774e42edd507a1ff34088ce0ccbe
--- /dev/null
+++ b/src/org/controlsfx/control/PrefixSelectionChoiceBox.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.tools.PrefixSelectionCustomizer;
+import javafx.scene.control.ChoiceBox;
+
+/**
+ * <p>A simple extension of the {@link ChoiceBox} which selects an entry of
+ * its item list based on keyboard input. The user can type letters or 
+ * digits on the keyboard and die {@link ChoiceBox} will attempt to
+ * select the first item it can find with a matching prefix.
+ *
+ * <p>This feature is available natively on the Windows combo box control, so many
+ * users have asked for it. There is a feature request to include this feature
+ * into JavaFX (<a href="https://javafx-jira.kenai.com/browse/RT-18064">Issue RT-18064</a>). 
+ * The class is published as part of ContorlsFX to allow testing and feedback.
+ * 
+ * <h3>Example</h3>
+ * 
+ * <p>Let's look at an example to clarify this. The choice box offers the items 
+ * ["Aaaaa", "Abbbb", "Abccc", "Abcdd", "Abcde"]. The user now types "abc" in 
+ * quick succession (and then stops typing). The choice box will select a new entry 
+ * on every key pressed. The first entry it will select is "Aaaaa" since it is the 
+ * first entry that starts with an "a" (case ignored). It will then select "Abbbb", 
+ * since this is the first entry that started with "ab" and will finally settle for 
+ * "Abccc".
+ * 
+ * <ul><table>
+ *   <tr><th>Keys typed</th><th>Element selected</th></tr>
+ *   <tr><td>a</td><td>Aaaaa<td></tr>
+ *   <tr><td>aaa</td><td>Aaaaa<td></tr>
+ *   <tr><td>ab</td><td>Abbbb<td></tr>
+ *   <tr><td>abc</td><td>Abccc<td></tr>
+ *   <tr><td>xyz</td><td>-<td></tr>
+ * </table></ul>
+ * 
+ * <p>If you want to modify an existing {@link ChoiceBox} you can use the
+ * {@link PrefixSelectionCustomizer} directly to do this.
+ * 
+ * @see PrefixSelectionCustomizer
+ */
+public class PrefixSelectionChoiceBox<T> extends ChoiceBox<T> {
+
+    /**
+     * Create a non editable {@link ChoiceBox} with the "prefix selection"
+     * feature installed.
+     */
+    public PrefixSelectionChoiceBox() {
+        PrefixSelectionCustomizer.customize(this);
+    }
+    
+}
diff --git a/src/org/controlsfx/control/PrefixSelectionComboBox.java b/src/org/controlsfx/control/PrefixSelectionComboBox.java
new file mode 100644
index 0000000000000000000000000000000000000000..98092f610fb5b1d88474afc05e98db0b5774e82a
--- /dev/null
+++ b/src/org/controlsfx/control/PrefixSelectionComboBox.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.tools.PrefixSelectionCustomizer;
+import javafx.scene.control.ComboBox;
+
+/**
+ * A simple extension of the {@link ComboBox} which selects an entry of
+ * its item list based on keyboard input. The user can  type letters or 
+ * digits on the keyboard and die ChoiceBox will attempt to
+ * select the first item it can find with a matching prefix.
+ * 
+ * This will only be enabled, when the {@link ComboBox} is not editable, so
+ * this class will be setup as non editable by default.
+ *
+ * <p>This feature is available natively on the Windows combo box control, so many
+ * users have asked for it. There is a feature request to include this feature
+ * into JavaFX (<a href="https://javafx-jira.kenai.com/browse/RT-18064">Issue RT-18064</a>). 
+ * The class is published as part of ContorlsFX to allow testing and feedback.
+ * 
+ * <h3>Example</h3>
+ * 
+ * <p>Let's look at an example to clarify this. The combo box offers the items 
+ * ["Aaaaa", "Abbbb", "Abccc", "Abcdd", "Abcde"]. The user now types "abc" in 
+ * quick succession (and then stops typing). The combo box will select a new entry 
+ * on every key pressed. The first entry it will select is "Aaaaa" since it is the 
+ * first entry that starts with an "a" (case ignored). It will then select "Abbbb", 
+ * since this is the first entry that started with "ab" and will finally settle for 
+ * "Abccc".
+ * 
+ * <ul><table>
+ *   <tr><th>Keys typed</th><th>Element selected</th></tr>
+ *   <tr><td>a</td><td>Aaaaa<td></tr>
+ *   <tr><td>aaa</td><td>Aaaaa<td></tr>
+ *   <tr><td>ab</td><td>Abbbb<td></tr>
+ *   <tr><td>abc</td><td>Abccc<td></tr>
+ *   <tr><td>xyz</td><td>-<td></tr>
+ * </table></ul>
+ * 
+ * <p>If you want to modify an existing {@link ComboBox} you can use the
+ * {@link PrefixSelectionCustomizer} directly to do this.
+ * 
+ * @see PrefixSelectionCustomizer
+ */
+public class PrefixSelectionComboBox<T> extends ComboBox<T> {
+
+    /**
+     * Create a non editable {@link ComboBox} with the "prefix selection"
+     * feature installed.
+     */
+    public PrefixSelectionComboBox() {
+        setEditable(false);
+        PrefixSelectionCustomizer.customize(this);
+    }
+    
+}
diff --git a/src/org/controlsfx/control/PropertySheet.java b/src/org/controlsfx/control/PropertySheet.java
new file mode 100644
index 0000000000000000000000000000000000000000..2675b7c24a8dcf57698903899d4cc5a0bf689f38
--- /dev/null
+++ b/src/org/controlsfx/control/PropertySheet.java
@@ -0,0 +1,452 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.PropertySheetSkin;
+
+import java.util.Optional;
+
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.control.Skin;
+import javafx.util.Callback;
+
+import org.controlsfx.property.BeanPropertyUtils;
+import org.controlsfx.property.editor.DefaultPropertyEditorFactory;
+import org.controlsfx.property.editor.Editors;
+import org.controlsfx.property.editor.PropertyEditor;
+
+/**
+ * The PropertySheet control is a powerful control designed to make it really
+ * easy for developers to present to end users a list of properties that the 
+ * end user is allowed to manipulate. Commonly a property sheet is used in
+ * visual editors and other tools where a lot of properties exist.
+ * 
+ * <p>To better describe what a property sheet is, please refer to the picture
+ * below:
+ * 
+ * <br>
+ * <center><img src="propertySheet.PNG" alt="Screenshot of PropertySheet"></center>
+ * 
+ * <p>In this property sheet there exists two columns: the left column shows a 
+ * label describing the property itself, whereas the right column provides a
+ * {@link PropertyEditor} that allows the end user the means to manipulate the
+ * property. In the screenshot you can see CheckEditor, 
+ * ChoiceEditor, TextEditor and FontEditor, among the
+ * many editors that are available in the {@link Editors}
+ * package.
+ * 
+ * <p>To create a PropertySheet is simple: you firstly instantiate an instance
+ * of PropertySheet, and then you pass in a list of {@link Item} instances,
+ * where each Item represents a single property that is to be editable by the
+ * end user.
+ * 
+ * <h3>Working with JavaBeans</h3>
+ * Because a very common use case for a property sheet is editing properties on
+ * a JavaBean, there is convenience API for making this interaction easier.
+ * Refer to the {@link BeanPropertyUtils class}, in particular the
+ * {@link BeanPropertyUtils#getProperties(Object)} method that will return a 
+ * list of Item instances, one Item instance per property on the given JavaBean.
+ * 
+ * @see Item
+ * @see Mode
+ */
+public class PropertySheet extends ControlsFXControl {
+    
+    
+    /**************************************************************************
+     * 
+     * Static fields
+     * 
+     **************************************************************************/
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Static enumerations / interfaces
+     * 
+     **************************************************************************/
+    
+    /**
+     * Specifies how the {@link PropertySheet} should be laid out. Refer to the 
+     * enumeration values to learn what each one means.
+     */
+    public static enum Mode {
+        /**
+         * Simply displays the properties in the 
+         * {@link PropertySheet#getItems() items list} in the order they are 
+         * in the list. 
+         */
+        NAME,
+        
+        /**
+         * Groups the properties in the 
+         * {@link PropertySheet#getItems() items list} based on their
+         * {@link Item#getCategory() category}.
+         */
+        CATEGORY
+    }
+    
+    
+    
+    /**
+     * A wrapper interface for a single property to be displayed in a
+     * {@link PropertySheet} control.
+     * 
+     * @see PropertySheet
+     */
+    public static interface Item {
+        
+        /**
+         * Returns the class type of the property.
+         */
+        public Class<?> getType();
+
+        /**
+         * Returns a String representation of the category of the property. This
+         * is relevant when the {@link PropertySheet} 
+         * {@link PropertySheet#modeProperty() mode property} is set to
+         * {@link Mode#CATEGORY} - as then all properties with the same category
+         * will be grouped together visually. 
+         */
+        public String getCategory();
+       
+        /**
+         * Returns the display name of the property, which should be short (i.e.
+         * less than two words). This is used to explain to the end user what the
+         * property represents and is displayed beside the {@link PropertyEditor}.
+         * If you need to explain more detail to the user, consider placing it
+         * in the {@link #getDescription()}.
+         */
+        public String getName();
+        
+        /**
+         * A String that will be shown to the user as a tooltip. This allows for
+         * a longer form of detail than what is possible with the {@link #getName()} 
+         * method.
+         */
+        public String getDescription();
+        
+        /**
+         * Returns the current value of the property.
+         */
+        public Object getValue();
+
+        /**
+         * Sets the current value of the property.
+         */
+        public void setValue(Object value);
+        
+        /**
+         * Returns the underlying ObservableValue, where one exists, that the editor 
+         * can monitor for changes.
+         */
+        public Optional<ObservableValue<? extends Object>> getObservableValue();
+        
+        /**
+         * Returns an Optional wrapping the class of the PropertyEditor that 
+         * should be used for editing this item. The default implementation 
+         * returns Optional.empty()
+         * 
+         * The class must have a constructor that can accept a single argument 
+         * of type PropertySheet.Item
+         */
+        default public Optional<Class<? extends PropertyEditor<?>>> getPropertyEditorClass() {
+            return Optional.empty();
+        }
+        
+        /**
+         *  Indicates whether the PropertySheet should allow editing of this 
+         * property, or whether it is read-only. The default implementation 
+         * returns true.
+         */
+        default public boolean isEditable() {
+            return true;
+        }
+   }
+    
+    
+    /**************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+    private final ObservableList<Item> items;
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Creates a default PropertySheet instance with no properties to edit.
+     */
+    public PropertySheet() {
+        this(null);
+    }
+    
+    /**
+     * Creates a PropertySheet instance prepopulated with the items provided
+     * in the items {@link ObservableList}.
+     * 
+     * @param items The items that should appear within the PropertySheet.
+     */
+    public PropertySheet(ObservableList<Item> items) {
+        getStyleClass().add(DEFAULT_STYLE_CLASS);
+        
+        this.items = items == null ? FXCollections.<Item>observableArrayList() : items;
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    /**
+     * 
+     * @return An ObservableList of properties that will be displayed to the user to allow for them
+     * to be edited. 
+     */
+    public ObservableList<Item> getItems() {
+        return items;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new PropertySheetSkin(this);
+    }
+    
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(PropertySheet.class, "propertysheet.css");
+    }
+
+    
+    /**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+    
+    // --- modeProperty 
+    private final SimpleObjectProperty<Mode> modeProperty = 
+            new SimpleObjectProperty<>(this, "mode", Mode.NAME); //$NON-NLS-1$
+    
+    /**
+     * Used to represent how the properties should be laid out in
+     * the PropertySheet. Refer to the {@link Mode} enumeration to better 
+     * understand the available options.
+     * @return A SimpleObjectproperty. 
+     */
+    public final SimpleObjectProperty<Mode> modeProperty() {
+    	return modeProperty;
+    }
+
+    /**
+     * @see Mode
+     * @return how the properties should be laid out in
+     * the PropertySheet.
+     */
+    public final Mode getMode() {
+        return modeProperty.get();
+    }
+
+    /**
+     * Set how the properties should be laid out in
+     * the PropertySheet.
+     * @param mode 
+     */
+    public final void setMode(Mode mode) {
+        modeProperty.set(mode);
+    }
+  
+
+    // --- propertyEditorFactory
+    private final SimpleObjectProperty<Callback<Item, PropertyEditor<?>>> propertyEditorFactory = 
+            new SimpleObjectProperty<>(this, "propertyEditor", new DefaultPropertyEditorFactory()); //$NON-NLS-1$
+    
+    /**
+     * The property editor factory is used by the PropertySheet to determine which
+     * {@link PropertyEditor} to use for a given {@link Item}. By default the
+     * {@link DefaultPropertyEditorFactory} is used, but this may be replaced
+     * or extended by developers wishing to add in (or substitute) their own
+     * property editors.
+     * 
+     * @return A SimpleObjectproperty.
+     */
+    public final SimpleObjectProperty<Callback<Item, PropertyEditor<?>>> propertyEditorFactory() {
+        return propertyEditorFactory;
+    }
+    
+    /**
+     * 
+     * @return The editor factory used by the PropertySheet to determine which
+     * {@link PropertyEditor} to use for a given {@link Item}.
+     */
+    public final Callback<Item, PropertyEditor<?>> getPropertyEditorFactory() {
+        return propertyEditorFactory.get();
+    }
+    
+    /**
+     * Sets a new editor factory used by the PropertySheet to determine which
+     * {@link PropertyEditor} to use for a given {@link Item}.
+     * @param factory 
+     */
+    public final void setPropertyEditorFactory( Callback<Item, PropertyEditor<?>> factory ) {
+        propertyEditorFactory.set( factory == null? new DefaultPropertyEditorFactory(): factory );
+    }
+    
+    
+    // --- modeSwitcherVisible
+    private final SimpleBooleanProperty modeSwitcherVisible = 
+            new SimpleBooleanProperty(this, "modeSwitcherVisible", true); //$NON-NLS-1$
+    
+    /**
+     * This property represents whether a visual option should be presented to
+     * users to switch between the various {@link Mode modes} available. By
+     * default this is true, so setting it to false will hide these buttons.
+     * @return A SimpleBooleanproperty.
+     */
+    public final SimpleBooleanProperty modeSwitcherVisibleProperty() {
+        return modeSwitcherVisible;
+    }
+    
+    /**
+     * 
+     * @return whether a visual option is presented to
+     * users to switch between the various {@link Mode modes} available.
+     */
+    public final boolean isModeSwitcherVisible() {
+        return modeSwitcherVisible.get();
+    }
+    
+    /**
+     * Set whether a visual option should be presented to
+     * users to switch between the various {@link Mode modes} available.
+     * @param visible 
+     */
+    public final void setModeSwitcherVisible( boolean visible ) {
+        modeSwitcherVisible.set(visible);
+    }
+    
+    
+    // --- toolbarSearchVisibleProperty
+    private final SimpleBooleanProperty searchBoxVisible = 
+            new SimpleBooleanProperty(this, "searchBoxVisible", true); //$NON-NLS-1$
+    
+    /**
+     * 
+     */
+    /**
+     * This property represents whether a text field should be presented to
+     * users to allow for them to filter the properties in the property sheet to
+     * only show ones matching the typed input. By default this is true, so 
+     * setting it to false will hide this search field.
+     * @return A SimpleBooleanProperty.
+     */
+    public final SimpleBooleanProperty searchBoxVisibleProperty() {
+        return searchBoxVisible;
+    }
+    
+    /**
+     * 
+     * @return whether a text field should be presented to
+     * users to allow for them to filter the properties in the property sheet to
+     * only show ones matching the typed input.
+     */
+    public final boolean isSearchBoxVisible() {
+        return searchBoxVisible.get();
+    }
+    
+    /**
+     * Sets whether a text field should be presented to
+     * users to allow for them to filter the properties in the property sheet to
+     * only show ones matching the typed input.
+     * @param visible 
+     */
+    public final void setSearchBoxVisible( boolean visible ) {
+        searchBoxVisible.set(visible);
+    }   
+    
+     
+    // --- titleFilterProperty
+    private final SimpleStringProperty titleFilterProperty = 
+            new SimpleStringProperty(this, "titleFilter", ""); //$NON-NLS-1$ //$NON-NLS-2$
+    
+    /**
+     * Regardless of whether the {@link #searchBoxVisibleProperty() search box}
+     * is visible or not, it is possible to filter the options shown on screen
+     * using this title filter property. If the search box is visible, it will
+     * manipulate this property to contain whatever the user types.
+     * @return A SimpleStringProperty.
+     */
+    public final SimpleStringProperty titleFilter() {
+        return titleFilterProperty;
+    }
+    
+    /**
+     * @see #titleFilter() 
+     * @return the filter for filtering the options shown on screen
+     */
+    public final String getTitleFilter() {
+        return titleFilterProperty.get();
+    }
+    
+    /**
+     * Sets the filter for filtering the options shown on screen.
+     * @param filter 
+     * @see #titleFilter() 
+     */
+    public final void setTitleFilter( String filter ) {
+        titleFilterProperty.set(filter);
+    }
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Stylesheet Handling                                                     *
+     *                                                                         *
+     **************************************************************************/
+
+    private static final String DEFAULT_STYLE_CLASS = "property-sheet"; //$NON-NLS-1$
+    
+}
diff --git a/src/org/controlsfx/control/RangeSlider.java b/src/org/controlsfx/control/RangeSlider.java
new file mode 100644
index 0000000000000000000000000000000000000000..b60462ac3847b4751730775762a16be649a6e96d
--- /dev/null
+++ b/src/org/controlsfx/control/RangeSlider.java
@@ -0,0 +1,1102 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.RangeSliderSkin;
+import org.controlsfx.tools.Utils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.DoublePropertyBase;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.css.CssMetaData;
+import javafx.css.PseudoClass;
+import javafx.css.StyleOrigin;
+import javafx.css.Styleable;
+import javafx.css.StyleableBooleanProperty;
+import javafx.css.StyleableDoubleProperty;
+import javafx.css.StyleableIntegerProperty;
+import javafx.css.StyleableObjectProperty;
+import javafx.css.StyleableProperty;
+import javafx.geometry.Orientation;
+import javafx.scene.control.Control;
+import javafx.scene.control.Skin;
+import javafx.scene.control.Slider;
+
+import com.sun.javafx.css.converters.BooleanConverter;
+import com.sun.javafx.css.converters.EnumConverter;
+import com.sun.javafx.css.converters.SizeConverter;
+
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.util.StringConverter;
+
+/**
+ * The RangeSlider control is simply a JavaFX {@link Slider} control with support
+ * for two 'thumbs', rather than one. A thumb is the non-technical name for the
+ * draggable area inside the Slider / RangeSlider that allows for a value to be
+ * set. 
+ * 
+ * <p>Because the RangeSlider has two thumbs, it also has a few additional rules
+ * and user interactions:
+ * 
+ * <ol>
+ *   <li>The 'lower value' thumb can not move past the 'higher value' thumb.
+ *   <li>Whereas the {@link Slider} control only has one 
+ *       {@link Slider#valueProperty() value} property, the RangeSlider has a 
+ *       {@link #lowValueProperty() low value} and a 
+ *       {@link #highValueProperty() high value} property, not surprisingly 
+ *       represented by the 'low value' and 'high value' thumbs.
+ *   <li>The area between the low and high values represents the allowable range.
+ *       For example, if the low value is 2 and the high value is 8, then the
+ *       allowable range is between 2 and 8. 
+ *   <li>The allowable range area is rendered differently. This area is able to 
+ *       be dragged with mouse / touch input to allow for the entire range to
+ *       be modified. For example, following on from the previous example of the
+ *       allowable range being between 2 and 8, if the user drags the range bar
+ *       to the right, the low value will adjust to 3, and the high value 9, and
+ *       so on until the user stops adjusting. 
+ * </ol>
+ * 
+ * <h3>Screenshots</h3>
+ * Because the RangeSlider supports both horizontal and vertical 
+ * {@link #orientationProperty() orientation}, there are two screenshots below:
+ * 
+ * <table border="0" summary="Screenshot of RangeSlider orientation">
+ *   <tr>
+ *     <td width="75" valign="center"><strong>Horizontal:</strong></td>
+ *     <td><img src="rangeSlider-horizontal.png" alt="Screenshot of a horizontal RangeSlider"></td>
+ *   </tr>
+ *   <tr>
+ *     <td width="75" valign="top"><strong>Vertical:</strong></td>
+ *     <td><img src="rangeSlider-vertical.png" alt="Screenshot of a vertical RangeSlider"></td>
+ *   </tr>
+ * </table>
+ * 
+ * <h3>Code Samples</h3>
+ * Instantiating a RangeSlider is simple. The first decision is to decide whether
+ * a horizontal or a vertical track is more appropriate. By default RangeSlider
+ * instances are horizontal, but this can be changed by setting the 
+ * {@link #orientationProperty() orientation} property.
+ * 
+ * <p>Once the orientation is determined, the next most important decision is
+ * to determine what the {@link #minProperty() min} / {@link #maxProperty() max}
+ * and default {@link #lowValueProperty() low} / {@link #highValueProperty() high}
+ * values are. The min / max values represent the smallest and largest legal
+ * values for the thumbs to be set to, whereas the low / high values represent
+ * where the thumbs are currently, within the bounds of the min / max values.
+ * Because all four values are required in all circumstances, they are all
+ * required parameters to instantiate a RangeSlider: the constructor takes
+ * four doubles, representing min, max, lowValue and highValue (in that order).
+ * 
+ * <p>For example, here is a simple horizontal RangeSlider that has a minimum
+ * value of 0, a maximum value of 100, a low value of 10 and a high value of 90: 
+ * 
+ * <pre>{@code final RangeSlider hSlider = new RangeSlider(0, 100, 10, 90);}</pre>
+ * 
+ * <p>To configure the hSlider to look like the RangeSlider in the horizontal
+ * RangeSlider screenshot above only requires a few additional properties to be 
+ * set:
+ * 
+ * <pre>
+ * {@code
+ * final RangeSlider hSlider = new RangeSlider(0, 100, 10, 90);
+ * hSlider.setShowTickMarks(true);
+ * hSlider.setShowTickLabels(true);
+ * hSlider.setBlockIncrement(10);}</pre>
+ * 
+ * <p>To create a vertical slider, simply do the following:
+ * 
+ * <pre>
+ * {@code
+ * final RangeSlider vSlider = new RangeSlider(0, 200, 30, 150);
+ * vSlider.setOrientation(Orientation.VERTICAL);}</pre>
+ * 
+ * <p>This code creates a RangeSlider with a min value of 0, a max value of 200,
+ * a low value of 30, and a high value of 150.
+ * 
+ * @see Slider
+ */
+public class RangeSlider extends ControlsFXControl {
+    
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+    
+    /**
+     * Creates a new RangeSlider instance using default values of 0.0, 0.25, 0.75
+     * and 1.0 for min/lowValue/highValue/max, respectively. 
+     */
+    public RangeSlider() {
+        this(0, 1.0, 0.25, 0.75);
+    }
+
+    /**
+     * Instantiates a default, horizontal RangeSlider with the specified 
+     * min/max/low/high values.
+     * 
+     * @param min The minimum allowable value that the RangeSlider will allow.
+     * @param max The maximum allowable value that the RangeSlider will allow.
+     * @param lowValue The initial value for the low value in the RangeSlider.
+     * @param highValue The initial value for the high value in the RangeSlider.
+     */
+    public RangeSlider(double min, double max, double lowValue, double highValue) {
+        getStyleClass().setAll(DEFAULT_STYLE_CLASS);
+        
+        setMax(max);
+        setMin(min);
+        adjustValues();
+        setLowValue(lowValue);
+        setHighValue(highValue);
+    }
+        
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(RangeSlider.class, "rangeslider.css");
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new RangeSliderSkin(this);
+    }
+  
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * New properties (over and above what is in Slider)                       *
+     *                                                                         *
+     **************************************************************************/
+    
+    // --- low value
+    /**
+     * The low value property represents the current position of the low value
+     * thumb, and is within the allowable range as specified by the
+     * {@link #minProperty() min} and {@link #maxProperty() max} properties. By
+     * default this value is 0.
+     */
+    public final DoubleProperty lowValueProperty() {
+        return lowValue;
+    }
+    private DoubleProperty lowValue = new SimpleDoubleProperty(this, "lowValue", 0.0D) { //$NON-NLS-1$
+        @Override protected void invalidated() {
+            adjustLowValues();
+        }
+    };
+    
+    /**
+     * Sets the low value for the range slider, which may or may not be clamped
+     * to be within the allowable range as specified by the
+     * {@link #minProperty() min} and {@link #maxProperty() max} properties.
+     */
+    public final void setLowValue(double d) {
+        lowValueProperty().set(d);
+    }
+
+    /**
+     * Returns the current low value for the range slider.
+     */
+    public final double getLowValue() {
+        return lowValue != null ? lowValue.get() : 0.0D;
+    }
+
+    
+    
+    // --- low value changing
+    /**
+     * When true, indicates the current low value of this RangeSlider is changing.
+     * It provides notification that the low value is changing. Once the low 
+     * value is computed, it is set back to false.
+     */
+    public final BooleanProperty lowValueChangingProperty() {
+        if (lowValueChanging == null) {
+            lowValueChanging = new SimpleBooleanProperty(this, "lowValueChanging", false); //$NON-NLS-1$
+        }
+        return lowValueChanging;
+    }
+    
+    private BooleanProperty lowValueChanging;
+
+    /**
+     * Call this when the low value is changing.
+     * @param value True if the low value is changing, false otherwise.
+     */
+    public final void setLowValueChanging(boolean value) {
+        lowValueChangingProperty().set(value);
+    }
+
+    /**
+     * Returns whether or not the low value of this RangeSlider is currently
+     * changing.
+     */
+    public final boolean isLowValueChanging() {
+        return lowValueChanging == null ? false : lowValueChanging.get();
+    }
+
+    
+    // --- high value
+    /**
+     * The high value property represents the current position of the high value
+     * thumb, and is within the allowable range as specified by the
+     * {@link #minProperty() min} and {@link #maxProperty() max} properties. By
+     * default this value is 100.
+     */
+    public final DoubleProperty highValueProperty() {
+        return highValue;
+    }
+    private DoubleProperty highValue = new SimpleDoubleProperty(this, "highValue", 100D) { //$NON-NLS-1$
+        @Override protected void invalidated() {
+            adjustHighValues();
+        }
+        
+        @Override public Object getBean() {
+            return RangeSlider.this;
+        }
+
+        @Override public String getName() {
+            return "highValue"; //$NON-NLS-1$
+        }
+    };
+    
+    /**
+     * Sets the high value for the range slider, which may or may not be clamped
+     * to be within the allowable range as specified by the
+     * {@link #minProperty() min} and {@link #maxProperty() max} properties.
+     */
+    public final void setHighValue(double d) {
+        if (!highValueProperty().isBound()) highValueProperty().set(d);
+    }
+
+    /**
+     * Returns the current high value for the range slider.
+     */
+    public final double getHighValue() {
+        return highValue != null ? highValue.get() : 100D;
+    }
+
+    
+
+    // --- high value changing
+    /**
+     * When true, indicates the current high value of this RangeSlider is changing.
+     * It provides notification that the high value is changing. Once the high 
+     * value is computed, it is set back to false.
+     */
+    public final BooleanProperty highValueChangingProperty() {
+        if (highValueChanging == null) {
+            highValueChanging = new SimpleBooleanProperty(this, "highValueChanging", false); //$NON-NLS-1$
+        }
+        return highValueChanging;
+    }
+    private BooleanProperty highValueChanging;
+
+    /**
+     * Call this when high low value is changing.
+     * @param value True if the high value is changing, false otherwise.
+     */
+    public final void setHighValueChanging(boolean value) {
+        highValueChangingProperty().set(value);
+    }
+
+    /**
+     * Returns whether or not the high value of this RangeSlider is currently
+     * changing.
+     */
+    public final boolean isHighValueChanging() {
+        return highValueChanging == null ? false : highValueChanging.get();
+    }
+    
+    private final ObjectProperty<StringConverter<Number>> tickLabelFormatter = new SimpleObjectProperty<>();
+    
+    /**
+     * Gets the value of the property tickLabelFormatter.
+     * @return the value of the property tickLabelFormatter.
+     */
+    public final StringConverter<Number> getLabelFormatter(){
+        return tickLabelFormatter.get();
+    }
+    
+    /**
+     * Sets the value of the property tickLabelFormatter.
+     * @param value 
+     */
+    public final void setLabelFormatter(StringConverter<Number> value){
+        tickLabelFormatter.set(value);
+    }
+    /**
+     * StringConverter used to format tick mark labels. If null a default will be used.
+     * @return a Property containing the StringConverter.
+     */
+    public final ObjectProperty<StringConverter<Number>> labelFormatterProperty(){
+        return tickLabelFormatter;
+    }
+    
+    /***************************************************************************
+     *                                                                         *
+     * New public API                                                          *
+     *                                                                         *
+     **************************************************************************/
+    
+    /**
+     * Increments the {@link #lowValueProperty() low value} by the 
+     * {@link #blockIncrementProperty() block increment} amount.
+     */
+    public void incrementLowValue() {
+        adjustLowValue(getLowValue() + getBlockIncrement());
+    }
+
+    /**
+     * Decrements the {@link #lowValueProperty() low value} by the 
+     * {@link #blockIncrementProperty() block increment} amount.
+     */
+    public void decrementLowValue() {
+        adjustLowValue(getLowValue() - getBlockIncrement());
+    }
+    
+    /**
+     * Increments the {@link #highValueProperty() high value} by the 
+     * {@link #blockIncrementProperty() block increment} amount.
+     */
+    public void incrementHighValue() {
+        adjustHighValue(getHighValue() + getBlockIncrement());
+    }
+
+    /**
+     * Decrements the {@link #highValueProperty() high value} by the 
+     * {@link #blockIncrementProperty() block increment} amount.
+     */
+    public void decrementHighValue() {
+        adjustHighValue(getHighValue() - getBlockIncrement());
+    }
+    
+    /**
+     * Adjusts {@link #lowValueProperty() lowValue} to match <code>newValue</code>,
+     * or as closely as possible within the constraints imposed by the 
+     * {@link #minProperty() min} and {@link #maxProperty() max} properties. 
+     * This function also takes into account 
+     * {@link #snapToTicksProperty() snapToTicks}, which is the main difference 
+     * between <code>adjustLowValue</code> and 
+     * {@link #setLowValue(double) setLowValue}.
+     */
+    public void adjustLowValue(double newValue) {
+        double d1 = getMin();
+        double d2 = getMax();
+        if (d2 <= d1) {
+            // no-op
+        } else {
+            newValue = newValue >= d1 ? newValue : d1;
+            newValue = newValue <= d2 ? newValue : d2;
+            setLowValue(snapValueToTicks(newValue));
+        }
+    }
+
+    /**
+     * Adjusts {@link #highValueProperty() highValue} to match <code>newValue</code>,
+     * or as closely as possible within the constraints imposed by the 
+     * {@link #minProperty() min} and {@link #maxProperty() max} properties. 
+     * This function also takes into account 
+     * {@link #snapToTicksProperty() snapToTicks}, which is the main difference 
+     * between <code>adjustHighValue</code> and 
+     * {@link #setHighValue(double) setHighValue}.
+     */
+    public void adjustHighValue(double newValue) {
+        double d1 = getMin();
+        double d2 = getMax();
+        if (d2 <= d1) {
+            // no-op
+        } else {
+            newValue = newValue >= d1 ? newValue : d1;
+            newValue = newValue <= d2 ? newValue : d2;
+            setHighValue(snapValueToTicks(newValue));
+        }
+    }
+
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Properties copied from Slider (and slightly edited)                     *
+     *                                                                         *
+     **************************************************************************/
+    
+    private DoubleProperty max;
+    
+    /**
+     * Sets the maximum value for this Slider.
+     * @param value 
+     */
+    public final void setMax(double value) {
+        maxProperty().set(value);
+    }
+
+    /**
+     * @return The maximum value of this slider. 100 is returned if
+     * the maximum value has never been set.
+     */
+    public final double getMax() {
+        return max == null ? 100 : max.get();
+    }
+
+    /**
+     * 
+     * @return A DoubleProperty representing the maximum value of this Slider. 
+     * This must be a value greater than {@link #minProperty() min}.
+     */
+    public final DoubleProperty maxProperty() {
+        if (max == null) {
+            max = new DoublePropertyBase(100) {
+                @Override protected void invalidated() {
+                    if (get() < getMin()) {
+                        setMin(get());
+                    }
+                    adjustValues();
+                }
+
+                @Override public Object getBean() {
+                    return RangeSlider.this;
+                }
+
+                @Override public String getName() {
+                    return "max"; //$NON-NLS-1$
+                }
+            };
+        }
+        return max;
+    }
+
+    private DoubleProperty min;
+    
+    /**
+     * Sets the minimum value for this Slider.
+     * @param value 
+     */
+    public final void setMin(double value) {
+        minProperty().set(value);
+    }
+
+    /**
+     * 
+     * @return the minimum value for this Slider. 0 is returned if the minimum
+     * has never been set.
+     */
+    public final double getMin() {
+        return min == null ? 0 : min.get();
+    }
+
+    /**
+     * 
+     * @return A DoubleProperty representing The minimum value of this Slider. 
+     * This must be a value less than {@link #maxProperty() max}.
+     */
+    public final DoubleProperty minProperty() {
+        if (min == null) {
+            min = new DoublePropertyBase(0) {
+                @Override protected void invalidated() {
+                    if (get() > getMax()) {
+                        setMax(get());
+                    }
+                    adjustValues();
+                }
+
+                @Override public Object getBean() {
+                    return RangeSlider.this;
+                }
+
+                @Override public String getName() {
+                    return "min"; //$NON-NLS-1$
+                }
+            };
+        }
+        return min;
+    }
+    
+    /**
+     * 
+     */
+    private BooleanProperty snapToTicks;
+    
+    /**
+     * Sets the value of SnapToTicks. 
+     * @see #snapToTicksProperty() 
+     * @param value 
+     */
+    public final void setSnapToTicks(boolean value) {
+        snapToTicksProperty().set(value);
+    }
+
+    /**
+     * 
+     * @return the value of SnapToTicks.
+     * @see #snapToTicksProperty() 
+     */
+    public final boolean isSnapToTicks() {
+        return snapToTicks == null ? false : snapToTicks.get();
+    }
+
+    /**
+     * Indicates whether the {@link #lowValueProperty()} value} / 
+     * {@link #highValueProperty()} value} of the {@code Slider} should always
+     * be aligned with the tick marks. This is honored even if the tick marks
+     * are not shown.
+     * @return A BooleanProperty.
+     */
+    public final BooleanProperty snapToTicksProperty() {
+        if (snapToTicks == null) {
+            snapToTicks = new StyleableBooleanProperty(false) {
+                @Override public CssMetaData<? extends Styleable, Boolean> getCssMetaData() {
+                    return RangeSlider.StyleableProperties.SNAP_TO_TICKS;
+                }
+
+                @Override public Object getBean() {
+                    return RangeSlider.this;
+                }
+
+                @Override public String getName() {
+                    return "snapToTicks"; //$NON-NLS-1$
+                }
+            };
+        }
+        return snapToTicks;
+    }
+    /**
+     * 
+     */
+    private DoubleProperty majorTickUnit;
+    
+    /**
+     * Sets the unit distance between major tick marks.
+     * @param value 
+     * @see #majorTickUnitProperty() 
+     */
+    public final void setMajorTickUnit(double value) {
+        if (value <= 0) {
+            throw new IllegalArgumentException("MajorTickUnit cannot be less than or equal to 0."); //$NON-NLS-1$
+        }
+        majorTickUnitProperty().set(value);
+    }
+
+    /**
+     * @see #majorTickUnitProperty() 
+     * @return The unit distance between major tick marks.
+     */
+    public final double getMajorTickUnit() {
+        return majorTickUnit == null ? 25 : majorTickUnit.get();
+    }
+
+    /**
+     * The unit distance between major tick marks. For example, if
+     * the {@link #minProperty() min} is 0 and the {@link #maxProperty() max} is 100 and the
+     * {@link #majorTickUnitProperty() majorTickUnit} is 25, then there would be 5 tick marks: one at
+     * position 0, one at position 25, one at position 50, one at position
+     * 75, and a final one at position 100.
+     * <p>
+     * This value should be positive and should be a value less than the
+     * span. Out of range values are essentially the same as disabling
+     * tick marks.
+     * 
+     * @return A DoubleProperty
+     */
+    public final DoubleProperty majorTickUnitProperty() {
+        if (majorTickUnit == null) {
+            majorTickUnit = new StyleableDoubleProperty(25) {
+                @Override public void invalidated() {
+                    if (get() <= 0) {
+                        throw new IllegalArgumentException("MajorTickUnit cannot be less than or equal to 0."); //$NON-NLS-1$
+                    }
+                }
+                
+                @Override public CssMetaData<? extends Styleable, Number> getCssMetaData() {
+                    return StyleableProperties.MAJOR_TICK_UNIT;
+                }
+
+                @Override public Object getBean() {
+                    return RangeSlider.this;
+                }
+
+                @Override public String getName() {
+                    return "majorTickUnit"; //$NON-NLS-1$
+                }
+            };
+        }
+        return majorTickUnit;
+    }
+    /**
+     * 
+     */
+    private IntegerProperty minorTickCount;
+    
+    /**
+     * Sets the number of minor ticks to place between any two major ticks.
+     * @param value 
+     * @see #minorTickCountProperty() 
+     */
+    public final void setMinorTickCount(int value) {
+        minorTickCountProperty().set(value);
+    }
+
+    /**
+     * @see #minorTickCountProperty() 
+     * @return The number of minor ticks to place between any two major ticks.
+     */
+    public final int getMinorTickCount() {
+        return minorTickCount == null ? 3 : minorTickCount.get();
+    }
+
+    /**
+     * The number of minor ticks to place between any two major ticks. This
+     * number should be positive or zero. Out of range values will disable
+     * disable minor ticks, as will a value of zero.
+     * @return An InterProperty
+     */
+    public final IntegerProperty minorTickCountProperty() {
+        if (minorTickCount == null) {
+            minorTickCount = new StyleableIntegerProperty(3) {
+                @Override public CssMetaData<? extends Styleable, Number> getCssMetaData() {
+                    return RangeSlider.StyleableProperties.MINOR_TICK_COUNT;
+                }
+
+                @Override public Object getBean() {
+                    return RangeSlider.this;
+                }
+
+                @Override public String getName() {
+                    return "minorTickCount"; //$NON-NLS-1$
+                }
+            };
+        }
+        return minorTickCount;
+    }
+    /**
+     *
+     */
+    private DoubleProperty blockIncrement;
+    
+    /**
+     * Sets the amount by which to adjust the slider if the track of the slider is
+     * clicked.
+     * @param value 
+     * @see #blockIncrementProperty() 
+     */
+    public final void setBlockIncrement(double value) {
+        blockIncrementProperty().set(value);
+    }
+
+    /**
+     * @see #blockIncrementProperty() 
+     * @return The amount by which to adjust the slider if the track of the slider is
+     * clicked.
+     */
+    public final double getBlockIncrement() {
+        return blockIncrement == null ? 10 : blockIncrement.get();
+    }
+
+    /**
+     *  The amount by which to adjust the slider if the track of the slider is
+     * clicked. This is used when manipulating the slider position using keys. If
+     * {@link #snapToTicksProperty() snapToTicks} is true then the nearest tick mark to the adjusted
+     * value will be used.
+     * @return A DoubleProperty
+     */
+    public final DoubleProperty blockIncrementProperty() {
+        if (blockIncrement == null) {
+            blockIncrement = new StyleableDoubleProperty(10) {
+                @Override public CssMetaData<? extends Styleable, Number> getCssMetaData() {
+                    return RangeSlider.StyleableProperties.BLOCK_INCREMENT;
+                }
+
+                @Override public Object getBean() {
+                    return RangeSlider.this;
+                }
+
+                @Override public String getName() {
+                    return "blockIncrement"; //$NON-NLS-1$
+                }
+            };
+        }
+        return blockIncrement;
+    }
+    
+    /**
+     * 
+     */
+    private ObjectProperty<Orientation> orientation;
+    
+    /**
+     * Sets the orientation of the Slider.
+     * @param value 
+     */
+    public final void setOrientation(Orientation value) {
+        orientationProperty().set(value);
+    }
+
+    /**
+     * 
+     * @return The orientation of the Slider. {@link Orientation#HORIZONTAL} is 
+     * returned by default.
+     */
+    public final Orientation getOrientation() {
+        return orientation == null ? Orientation.HORIZONTAL : orientation.get();
+    }
+
+    /**
+     * The orientation of the {@code Slider} can either be horizontal
+     * or vertical.
+     * @return An Objectproperty representing the orientation of the Slider.
+     */
+    public final ObjectProperty<Orientation> orientationProperty() {
+        if (orientation == null) {
+            orientation = new StyleableObjectProperty<Orientation>(Orientation.HORIZONTAL) {
+                @Override protected void invalidated() {
+                    final boolean vertical = (get() == Orientation.VERTICAL);
+                    pseudoClassStateChanged(VERTICAL_PSEUDOCLASS_STATE, vertical);
+                    pseudoClassStateChanged(HORIZONTAL_PSEUDOCLASS_STATE, ! vertical);
+                }
+                
+                @Override public CssMetaData<? extends Styleable, Orientation> getCssMetaData() {
+                    return RangeSlider.StyleableProperties.ORIENTATION;
+                }
+
+                @Override public Object getBean() {
+                    return RangeSlider.this;
+                }
+
+                @Override public String getName() {
+                    return "orientation"; //$NON-NLS-1$
+                }
+            };
+        }
+        return orientation;
+    }
+    
+    private BooleanProperty showTickLabels;
+    
+    /**
+     * Sets whether labels of tick marks should be shown or not.
+     * @param value 
+     */
+    public final void setShowTickLabels(boolean value) {
+        showTickLabelsProperty().set(value);
+    }
+
+    /**
+     * @return whether labels of tick marks are being shown.
+     */
+    public final boolean isShowTickLabels() {
+        return showTickLabels == null ? false : showTickLabels.get();
+    }
+
+    /**
+     * Indicates that the labels for tick marks should be shown. Typically a
+     * {@link Skin} implementation will only show labels if
+     * {@link #showTickMarksProperty() showTickMarks} is also true.
+     * @return A BooleanProperty
+     */
+    public final BooleanProperty showTickLabelsProperty() {
+        if (showTickLabels == null) {
+            showTickLabels = new StyleableBooleanProperty(false) {
+                @Override public CssMetaData<? extends Styleable, Boolean> getCssMetaData() {
+                    return RangeSlider.StyleableProperties.SHOW_TICK_LABELS;
+                }
+
+                @Override public Object getBean() {
+                    return RangeSlider.this;
+                }
+
+                @Override public String getName() {
+                    return "showTickLabels"; //$NON-NLS-1$
+                }
+            };
+        }
+        return showTickLabels;
+    }
+    /**
+     * 
+     */
+    private BooleanProperty showTickMarks;
+    
+    /**
+     * Specifies whether the {@link Skin} implementation should show tick marks.
+     * @param value 
+     */
+    public final void setShowTickMarks(boolean value) {
+        showTickMarksProperty().set(value);
+    }
+
+    /**
+     * 
+     * @return whether the {@link Skin} implementation should show tick marks.
+     */
+    public final boolean isShowTickMarks() {
+        return showTickMarks == null ? false : showTickMarks.get();
+    }
+
+    /**
+     * @return A BooleanProperty that specifies whether the {@link Skin} 
+     * implementation should show tick marks.
+     */
+    public final BooleanProperty showTickMarksProperty() {
+        if (showTickMarks == null) {
+            showTickMarks = new StyleableBooleanProperty(false) {
+                @Override public CssMetaData<? extends Styleable, Boolean> getCssMetaData() {
+                    return RangeSlider.StyleableProperties.SHOW_TICK_MARKS;
+                }
+
+                @Override public Object getBean() {
+                    return RangeSlider.this;
+                }
+
+                @Override public String getName() {
+                    return "showTickMarks"; //$NON-NLS-1$
+                }
+            };
+        }
+        return showTickMarks;
+    }
+    
+
+    
+     /***************************************************************************
+     *                                                                         *
+     * Private methods                                                         *
+     *                                                                         *
+     **************************************************************************/    
+    
+    /**
+     * Ensures that min is always < max, that value is always
+     * somewhere between the two, and that if snapToTicks is set then the
+     * value will always be set to align with a tick mark.
+     */
+    private void adjustValues() {
+        adjustLowValues();
+        adjustHighValues();
+    }
+
+    private void adjustLowValues() {
+        /**
+         * We first look if the LowValue is between the min and max.
+         */
+        if (getLowValue() < getMin() || getLowValue() > getMax()) {
+            double value = Utils.clamp(getMin(), getLowValue(), getMax());
+            setLowValue(value);
+        /**
+         * If the LowValue seems right, we check if it's not superior to
+         * HighValue ONLY if the highValue itself is right. Because it may
+         * happen that the highValue has not yet been computed and is
+         * wrong, and therefore force the lowValue to change in a wrong way
+         * which may end up in an infinite loop.
+         */
+        } else if (getLowValue() >= getHighValue() && (getHighValue() >= getMin() && getHighValue() <= getMax())) {
+            double value = Utils.clamp(getMin(), getLowValue(), getHighValue());
+            setLowValue(value);
+        }
+    }
+    
+    private double snapValueToTicks(double d) {
+        double d1 = d;
+        if (isSnapToTicks()) {
+            double d2 = 0.0D;
+            if (getMinorTickCount() != 0) {
+                d2 = getMajorTickUnit() / (double) (Math.max(getMinorTickCount(), 0) + 1);
+            } else {
+                d2 = getMajorTickUnit();
+            }
+            int i = (int) ((d1 - getMin()) / d2);
+            double d3 = (double) i * d2 + getMin();
+            double d4 = (double) (i + 1) * d2 + getMin();
+            d1 = Utils.nearest(d3, d1, d4);
+        }
+        return Utils.clamp(getMin(), d1, getMax());
+    }
+
+    private void adjustHighValues() {
+        if (getHighValue() < getMin() || getHighValue() > getMax()) {
+            setHighValue(Utils.clamp(getMin(), getHighValue(), getMax()));
+        } else if (getHighValue() < getLowValue() && (getLowValue() >= getMin() && getLowValue() <= getMax())) {
+            setHighValue(Utils.clamp(getLowValue(), getHighValue(), getMax()));
+        }
+    }
+
+    
+    
+    /**************************************************************************
+    *                                                                         *
+    * Stylesheet Handling                                                     *
+    *                                                                         *
+    **************************************************************************/
+    
+    private static final String DEFAULT_STYLE_CLASS = "range-slider"; //$NON-NLS-1$
+    
+    private static class StyleableProperties {
+        private static final CssMetaData<RangeSlider,Number> BLOCK_INCREMENT =
+            new CssMetaData<RangeSlider,Number>("-fx-block-increment", //$NON-NLS-1$
+                SizeConverter.getInstance(), 10.0) {
+
+            @Override public boolean isSettable(RangeSlider n) {
+                return n.blockIncrement == null || !n.blockIncrement.isBound();
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override public StyleableProperty<Number> getStyleableProperty(RangeSlider n) {
+                return (StyleableProperty<Number>)n.blockIncrementProperty();
+            }
+        };
+        
+        private static final CssMetaData<RangeSlider,Boolean> SHOW_TICK_LABELS =
+            new CssMetaData<RangeSlider,Boolean>("-fx-show-tick-labels", //$NON-NLS-1$
+                BooleanConverter.getInstance(), Boolean.FALSE) {
+
+            @Override public boolean isSettable(RangeSlider n) {
+                return n.showTickLabels == null || !n.showTickLabels.isBound();
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override public StyleableProperty<Boolean> getStyleableProperty(RangeSlider n) {
+                return (StyleableProperty<Boolean>)n.showTickLabelsProperty();
+            }
+        };
+                    
+        private static final CssMetaData<RangeSlider,Boolean> SHOW_TICK_MARKS =
+            new CssMetaData<RangeSlider,Boolean>("-fx-show-tick-marks", //$NON-NLS-1$
+                BooleanConverter.getInstance(), Boolean.FALSE) {
+
+            @Override public boolean isSettable(RangeSlider n) {
+                return n.showTickMarks == null || !n.showTickMarks.isBound();
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override public StyleableProperty<Boolean> getStyleableProperty(RangeSlider n) {
+                return (StyleableProperty<Boolean>)n.showTickMarksProperty();
+            }
+        };
+            
+        private static final CssMetaData<RangeSlider,Boolean> SNAP_TO_TICKS =
+            new CssMetaData<RangeSlider,Boolean>("-fx-snap-to-ticks", //$NON-NLS-1$
+                BooleanConverter.getInstance(), Boolean.FALSE) {
+
+            @Override public boolean isSettable(RangeSlider n) {
+                return n.snapToTicks == null || !n.snapToTicks.isBound();
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override public StyleableProperty<Boolean> getStyleableProperty(RangeSlider n) {
+                return (StyleableProperty<Boolean>)n.snapToTicksProperty();
+            }
+        };
+        
+        private static final CssMetaData<RangeSlider,Number> MAJOR_TICK_UNIT =
+            new CssMetaData<RangeSlider,Number>("-fx-major-tick-unit", //$NON-NLS-1$
+                SizeConverter.getInstance(), 25.0) {
+
+            @Override public boolean isSettable(RangeSlider n) {
+                return n.majorTickUnit == null || !n.majorTickUnit.isBound();
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override public StyleableProperty<Number> getStyleableProperty(RangeSlider n) {
+                return (StyleableProperty<Number>)n.majorTickUnitProperty();
+            }
+        };
+        
+        private static final CssMetaData<RangeSlider,Number> MINOR_TICK_COUNT =
+            new CssMetaData<RangeSlider,Number>("-fx-minor-tick-count", //$NON-NLS-1$
+                SizeConverter.getInstance(), 3.0) {
+
+            @SuppressWarnings("deprecation")
+            @Override public void set(RangeSlider node, Number value, StyleOrigin origin) {
+                super.set(node, value.intValue(), origin);
+            } 
+            
+            @Override public boolean isSettable(RangeSlider n) {
+                return n.minorTickCount == null || !n.minorTickCount.isBound();
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override public StyleableProperty<Number> getStyleableProperty(RangeSlider n) {
+                return (StyleableProperty<Number>)n.minorTickCountProperty();
+            }
+        };
+        
+        private static final CssMetaData<RangeSlider,Orientation> ORIENTATION =
+            new CssMetaData<RangeSlider,Orientation>("-fx-orientation", //$NON-NLS-1$
+                new EnumConverter<>(Orientation.class), 
+                Orientation.HORIZONTAL) {
+
+            @Override public Orientation getInitialValue(RangeSlider node) {
+                // A vertical Slider should remain vertical 
+                return node.getOrientation();
+            }
+
+            @Override public boolean isSettable(RangeSlider n) {
+                return n.orientation == null || !n.orientation.isBound();
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override public StyleableProperty<Orientation> getStyleableProperty(RangeSlider n) {
+                return (StyleableProperty<Orientation>)n.orientationProperty();
+            }
+        };
+
+        private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
+        static {
+            final List<CssMetaData<? extends Styleable, ?>> styleables = 
+                    new ArrayList<>(Control.getClassCssMetaData());
+            styleables.add(BLOCK_INCREMENT);
+            styleables.add(SHOW_TICK_LABELS);
+            styleables.add(SHOW_TICK_MARKS);
+            styleables.add(SNAP_TO_TICKS);
+            styleables.add(MAJOR_TICK_UNIT);
+            styleables.add(MINOR_TICK_COUNT);
+            styleables.add(ORIENTATION);
+
+            STYLEABLES = Collections.unmodifiableList(styleables);
+        }
+    }
+    
+
+    /**
+     * @return The CssMetaData associated with this class, which may include the
+     * CssMetaData of its super classes.
+     */
+    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
+        return StyleableProperties.STYLEABLES;
+    }
+
+    private static final PseudoClass VERTICAL_PSEUDOCLASS_STATE =
+            PseudoClass.getPseudoClass("vertical"); //$NON-NLS-1$
+    private static final PseudoClass HORIZONTAL_PSEUDOCLASS_STATE =
+            PseudoClass.getPseudoClass("horizontal"); //$NON-NLS-1$
+}
diff --git a/src/org/controlsfx/control/Rating.java b/src/org/controlsfx/control/Rating.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5f1f34aead1fdcd79a77a10f995cfaeaf0df6f0
--- /dev/null
+++ b/src/org/controlsfx/control/Rating.java
@@ -0,0 +1,317 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.RatingSkin;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.geometry.Orientation;
+import javafx.scene.control.Skin;
+
+/**
+ * A control for allowing users to provide a rating. This control supports
+ * {@link #partialRatingProperty() partial ratings} (i.e. not whole numbers and
+ * dependent upon where the user clicks in the control) and 
+ * {@link #updateOnHoverProperty() updating the rating on hover}. Read on for
+ * more examples!
+ * 
+ * <h3>Examples</h3>
+ * It can be hard to appreciate some of the features of the Rating control, so
+ * hopefully the following screenshots will help. Firstly, here is what the 
+ * standard (horizontal) Rating control looks like when it has five stars, and a 
+ * rating of two:
+ * 
+ * <br>
+ * <center>
+ * <img src="rating-horizontal.png" alt="Screenshot of horizontal Rating">
+ * </center>
+ * 
+ * <p>To create a Rating control that looks like this is simple:
+ * 
+ * <pre>
+ * {@code 
+ * final Rating rating = new Rating();}</pre>
+ * 
+ * <p>This creates a default horizontal rating control. To create a vertical 
+ * Rating control, simply change the orientation, as such:
+ * 
+ * <pre>
+ * {@code 
+ * final Rating rating = new Rating();
+ * rating.setOrientation(Orientation.VERTICAL);}</pre>
+ * 
+ * <p>The end result of making this one line change is shown in the screenshot
+ * below:
+ * 
+ * <br>
+ * <center>
+ * <img src="rating-vertical.png" alt="Screenshot of vertical Rating">
+ * </center>
+ * 
+ * <p>One of the features of the Rating control is that it doesn't just allow
+ * for 'integer' ratings: it also allows for the user to click anywhere within
+ * the rating area to set a 'float' rating. This is hard to describe, but easy 
+ * to show in a picture:
+ * 
+ * <br>
+ * <center>
+ * <img src="rating-partial.png" alt="Screenshot of partial Rating">
+ * </center>
+ * 
+ * <p>In essence, in the screenshot above, the user clicked roughly in the 
+ * middle of the third star. This results in a rating of approximately 2.44.
+ * To enable {@link #partialRatingProperty() partial ratings}, simply do the
+ * following when instantiating the Rating control:
+ * 
+ * <pre>
+ * {@code 
+ * final Rating rating = new Rating();
+ * rating.setPartialRating(true);}</pre>
+ * 
+ * <p>So far all of the Rating controls demonstrated above have
+ * required the user to click on the stars to register their rating. This may not
+ * be the preferred user interaction - often times the preferred approach is to
+ * simply allow for the rating to be registered by the user hovering their mouse
+ * over the rating stars. This mode is also supported by the Rating control,
+ * using the {@link #updateOnHoverProperty() update on hover} property, as such:
+ * 
+ * <pre>
+ * {@code 
+ * final Rating rating = new Rating();
+ * rating.setUpdateOnHover(true);}</pre>
+ * 
+ * <p>It is also allowable to have a Rating control that both updates on hover
+ * and allows for partial values: the 'golden fill' of the default graphics will
+ * automatically follow the users mouse as they move it along the Rating scale.
+ * To enable this, just set both properties to true.
+ */
+public class Rating extends ControlsFXControl {
+    
+    /***************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Creates a default instance with a minimum rating of 0 and a maximum 
+     * rating of 5.
+     */
+    public Rating() {
+        this(5);
+    }
+    
+    /**
+     * Creates a default instance with a minimum rating of 0 and a maximum rating
+     * as provided by the argument.
+     * 
+     * @param max The maximum allowed rating value.
+     */
+    public Rating(int max) {
+        this(max, -1);
+    }
+    
+    /**
+     * Creates a Rating instance with a minimum rating of 0, a maximum rating
+     * as provided by the {@code max} argument, and a current rating as provided
+     * by the {@code rating} argument.
+     * 
+     * @param max The maximum allowed rating value.
+     */
+    public Rating(int max, int rating) {
+        getStyleClass().setAll("rating"); //$NON-NLS-1$
+        
+        setMax(max);
+        setRating(rating == -1 ? (int) Math.floor(max / 2.0) : rating);
+    }
+    
+    
+    
+    /***************************************************************************
+     * 
+     * Overriding public API
+     * 
+     **************************************************************************/
+    
+    /** {@inheritDoc} */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new RatingSkin(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(Rating.class, "rating.css");
+    }
+    
+    /***************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+    
+    // --- Rating
+    /**
+     * The current rating value.
+     */
+    public final DoubleProperty ratingProperty() {
+        return rating;
+    }
+    private DoubleProperty rating = new SimpleDoubleProperty(this, "rating", 3); //$NON-NLS-1$
+    
+    /**
+     * Sets the current rating value.
+     */
+    public final void setRating(double value) {
+       ratingProperty().set(value);
+    }
+    
+    /**
+     * Returns the current rating value.
+     */
+    public final double getRating() {
+        return rating == null ? 3 : rating.get();
+    }
+
+    
+    // --- Max
+    /**
+     * The maximum-allowed rating value.
+     */
+    public final IntegerProperty maxProperty() {
+        return max;
+    }
+    private IntegerProperty max = new SimpleIntegerProperty(this, "max", 5); //$NON-NLS-1$
+    
+    /**
+     * Sets the maximum-allowed rating value.
+     */
+    public final void setMax(int value) {
+       maxProperty().set(value);
+    }
+
+    /**
+     * Returns the maximum-allowed rating value.
+     */
+    public final int getMax() {
+        return max == null ? 5 : max.get();
+    }
+    
+    
+    // --- Orientation
+    /**
+     * The {@link Orientation} of the {@code Rating} - this can either be 
+     * horizontal or vertical.
+     */
+    public final ObjectProperty<Orientation> orientationProperty() {
+        if (orientation == null) {
+            orientation = new SimpleObjectProperty<>(this, "orientation", Orientation.HORIZONTAL); //$NON-NLS-1$
+        }
+        return orientation;
+    }
+    private ObjectProperty<Orientation> orientation;
+    
+    /**
+     * Sets the {@link Orientation} of the {@code Rating} - this can either be 
+     * horizontal or vertical.
+     */
+    public final void setOrientation(Orientation value) {
+        orientationProperty().set(value);
+    };
+    
+    /**
+     * Returns the {@link Orientation} of the {@code Rating} - this can either 
+     * be horizontal or vertical.
+     */
+    public final Orientation getOrientation() {
+        return orientation == null ? Orientation.HORIZONTAL : orientation.get();
+    }
+
+    
+    // --- partial rating
+    /**
+     * If true this allows for users to set a rating as a floating point value.
+     * In other words, the range of the rating 'stars' can be thought of as a
+     * range between [0, max], and whereever the user clicks will be calculated
+     * as the new rating value. If this is false the more typical approach is used
+     * where the selected 'star' is used as the rating.
+     */
+    public final BooleanProperty partialRatingProperty() {
+        return partialRating;
+    }
+    private BooleanProperty partialRating = new SimpleBooleanProperty(this, "partialRating", false); //$NON-NLS-1$
+    
+    /**
+     * Sets whether {@link #partialRatingProperty() partial rating} support is
+     * enabled or not.
+     */
+    public final void setPartialRating(boolean value) {
+        partialRatingProperty().set(value);
+    }
+    
+    /**
+     * Returns whether {@link #partialRatingProperty() partial rating} support is
+     * enabled or not.
+     */
+    public final boolean isPartialRating() {
+        return partialRating == null ? false : partialRating.get();
+    }
+
+    
+    // --- update on hover
+    /**
+     * If true this allows for the {@link #ratingProperty() rating property} to
+     * be updated simply by the user hovering their mouse over the control. If
+     * false the user is required to click on their preferred rating to register
+     * the new rating with this control.
+     */
+    public final BooleanProperty updateOnHoverProperty() {
+        return updateOnHover;
+    }
+    private BooleanProperty updateOnHover = new SimpleBooleanProperty(this, "updateOnHover", false); //$NON-NLS-1$
+    
+    /**
+     * Sets whether {@link #updateOnHoverProperty() update on hover} support is
+     * enabled or not.
+     */
+    public final void setUpdateOnHover(boolean value) {
+        updateOnHoverProperty().set(value);
+    }
+    
+    /**
+     * Returns whether {@link #updateOnHoverProperty() update on hover} support is
+     * enabled or not.
+     */
+    public final boolean isUpdateOnHover() {
+        return updateOnHover == null ? false : updateOnHover.get();
+    }
+}
diff --git a/src/org/controlsfx/control/SegmentedButton.java b/src/org/controlsfx/control/SegmentedButton.java
new file mode 100644
index 0000000000000000000000000000000000000000..b27f81a155efb40654b79ade5d1fca0e9bb2c97e
--- /dev/null
+++ b/src/org/controlsfx/control/SegmentedButton.java
@@ -0,0 +1,241 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.SegmentedButtonSkin;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.control.Skin;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.control.ToggleGroup;
+
+/**
+ * The SegmentedButton is a simple control that forces together a group of
+ * {@link ToggleButton} instances such that they appear as one collective button
+ * (with sub-buttons), rather than as individual buttons. This is better 
+ * clarified with a picture:
+ * 
+ * <br>
+ * <center>
+ * <img src="segmentedButton.png" alt="Screenshot of SegmentedButton">
+ * </center>
+ * 
+ * <h3>Code Samples</h3>
+ * 
+ * <p>There is very little API on this control, you essentially create
+ * {@link ToggleButton} instances as per usual (and don't bother putting them
+ * into a {@link ToggleGroup}, as this is done by the SegmentedButton itself), and then 
+ * you place these buttons inside the {@link #getButtons() buttons list}. The 
+ * long-hand way to code this is as follows:
+ * 
+ * <pre>
+ * {@code 
+ * ToggleButton b1 = new ToggleButton("day");
+ * ToggleButton b2 = new ToggleButton("week");
+ * ToggleButton b3 = new ToggleButton("month");
+ * ToggleButton b4 = new ToggleButton("year");
+ *       
+ * SegmentedButton segmentedButton = new SegmentedButton();    
+ * segmentedButton.getButtons().addAll(b1, b2, b3, b4);}</pre>
+ * 
+ * <p>A slightly shorter way of doing this is to pass the ToggleButton instances
+ * into the varargs constructor, as such:
+ * 
+ * <pre>{@code SegmentedButton segmentedButton = new SegmentedButton(b1, b2, b3, b4);}</pre>
+ * 
+ * <h3>Custom ToggleGroup</h3>
+ * <p>It is possible to configure the ToggleGroup, which is used internally.
+ * By setting the ToggleGroup to null, the control will allow multiple selections.
+ * 
+ * <pre>
+ * {@code 
+ * SegmentedButton segmentedButton = new SegmentedButton();
+ * segmentedButton.setToggleGroup(null);
+ * }</pre>
+ *  
+ * <h3>Alternative Styling</h3>
+ * <p>As is visible in the screenshot at the top of this class documentation, 
+ * there are two different styles supported by the SegmentedButton control.
+ * Firstly, there is the default style based on the JavaFX Modena look. The 
+ * alternative style is what is currently referred to as the 'dark' look. To 
+ * enable this functionality, simply do the following:
+ * 
+ * <pre>
+ * {@code
+ * SegmentedButton segmentedButton = new SegmentedButton();   
+ * segmentedButton.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK);
+ * }</pre>
+ *
+ * <h3>Resizable Range</h3>
+ * <p>By default, the maximum width and height of a SegmentedButton match its
+ * preferred width and height. Thus, the SegmentedButton only fills the area
+ * which is necessary to display the contained buttons. To change this behavior,
+ * the following code can be used:
+ *
+ * <pre>
+ * {@code
+ * SegmentedButton segmentedButton = new SegmentedButton();
+ * segmentedButton.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
+ * }</pre>
+ * 
+ * @see ToggleButton
+ * @see ToggleGroup
+ */
+public class SegmentedButton extends ControlsFXControl {
+    
+    /**************************************************************************
+     * 
+     * Static fields
+     * 
+     *************************************************************************/
+    
+    /**
+     * An alternative styling for the segmented button, with a darker pressed 
+     * color which stands out more than the default modena styling. Refer to
+     * the class documentation for details on how to use (and screenshots), but
+     * in short, simply do the following to get the dark styling:
+     * 
+     * <pre>
+     * {@code
+     * SegmentedButton segmentedButton = new SegmentedButton();   
+     * segmentedButton.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK);
+     * }</pre>
+     */
+    public static final String STYLE_CLASS_DARK = "dark"; //$NON-NLS-1$
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Private fields
+     * 
+     *************************************************************************/
+    
+    private final ObservableList<ToggleButton> buttons;
+    private final ObjectProperty<ToggleGroup> toggleGroup = new SimpleObjectProperty<>(new ToggleGroup());
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     *************************************************************************/
+    
+    /**
+     * Creates a default SegmentedButton instance with no buttons.
+     */
+    public SegmentedButton() {
+        this((ObservableList<ToggleButton>)null);
+    }
+    
+    /**
+     * Creates a default SegmentedButton instance with the provided buttons
+     * inserted into it.
+     * 
+     * @param buttons A varargs array of buttons to add into the SegmentedButton
+     *      instance.
+     */
+    public SegmentedButton(ToggleButton... buttons) {
+        this(buttons == null ? 
+                FXCollections.<ToggleButton>observableArrayList() : 
+                FXCollections.observableArrayList(buttons));
+    }
+    
+    /**
+     * Creates a default SegmentedButton instance with the provided buttons
+     * inserted into it.
+     * 
+     * @param buttons A list of buttons to add into the SegmentedButton instance.
+     */
+    public SegmentedButton(ObservableList<ToggleButton> buttons) {
+        getStyleClass().add("segmented-button"); //$NON-NLS-1$
+        this.buttons = buttons == null ? FXCollections.<ToggleButton>observableArrayList() : buttons;
+        
+        // Fix for Issue #87:
+        // https://bitbucket.org/controlsfx/controlsfx/issue/87/segmentedbutton-keyboard-focus-traversal
+        setFocusTraversable(false);
+    }
+    
+
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     *************************************************************************/
+    
+    /** {@inheritDoc} */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new SegmentedButtonSkin(this);
+    }
+    
+    /**
+     * Returns the list of buttons that this SegmentedButton will draw together
+     * into one 'grouped button'. It is possible to modify this list to add or
+     * remove {@link ToggleButton} instances, as shown in the javadoc 
+     * documentation for this class.
+     */
+    public final ObservableList<ToggleButton> getButtons() {
+        return buttons;
+    }
+    
+    /**
+     * @return Property of the ToggleGroup used internally 
+     */
+    public ObjectProperty<ToggleGroup> toggleGroupProperty() {
+        return this.toggleGroup;
+    }
+
+    /**
+     * @return ToggleGroup used internally 
+     */
+    public ToggleGroup getToggleGroup() {
+        return this.toggleGroupProperty().getValue();
+    }
+
+    /**
+     * @param toggleGroup ToggleGroup to be used internally 
+     */
+    public void setToggleGroup(final ToggleGroup toggleGroup) {
+        this.toggleGroupProperty().setValue(toggleGroup);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * CSS
+     * 
+     *************************************************************************/
+    
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(SegmentedButton.class, "segmentedbutton.css");
+    }
+
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/SnapshotView.java b/src/org/controlsfx/control/SnapshotView.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a9f48045bd08242c709551e7e509780e73870de
--- /dev/null
+++ b/src/org/controlsfx/control/SnapshotView.java
@@ -0,0 +1,1733 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import static javafx.beans.binding.Bindings.and;
+import static javafx.beans.binding.Bindings.isNotNull;
+import static javafx.beans.binding.Bindings.notEqual;
+import impl.org.controlsfx.skin.SnapshotViewSkin;
+import impl.org.controlsfx.tools.rectangle.Rectangles2D;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.ReadOnlyBooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.MapChangeListener;
+import javafx.collections.ObservableMap;
+import javafx.css.CssMetaData;
+import javafx.css.StyleConverter;
+import javafx.css.Styleable;
+import javafx.css.StyleableDoubleProperty;
+import javafx.css.StyleableObjectProperty;
+import javafx.css.StyleableProperty;
+import javafx.geometry.Bounds;
+import javafx.geometry.Point2D;
+import javafx.geometry.Rectangle2D;
+import javafx.scene.Node;
+import javafx.scene.SnapshotParameters;
+import javafx.scene.control.Control;
+import javafx.scene.control.Skin;
+import javafx.scene.image.WritableImage;
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+
+/**
+ * A {@code SnapshotView} is a control which allows the user to select an area of a node in the typical manner used by
+ * picture editors and crate snapshots of the selection.
+ * <p>
+ * While holding the left mouse key down, a rectangular selection can be drawn. This selection can be moved, resized in
+ * eight cardinal directions and removed. Additionally, the selection's ratio can be fixed in which case the user's
+ * resizing will be limited such that the ratio is always upheld.
+ * <p>
+ * The area where the selection is possible is either this entire control or limited to the displayed node.
+ * 
+ * <h3>Screenshots</h3>
+ * <center><img src="snapshotView.png" alt="Screenshot of SnapshotView"></center>
+ * 
+ * <h3>Code Samples</h3>
+ * The following snippet creates a new instance with the ControlsFX logo loaded from the web, sets a selected area and
+ * fixes its ratio:
+ * 
+ * <pre>
+ * ImageView controlsFxView = new ImageView(
+ *         &quot;http://cache.fxexperience.com/wp-content/uploads/2013/05/ControlsFX.png&quot;);
+ * SnapshotView snapshotView = new SnapshotView(controlsFxView);
+ * snapshotView.setSelection(33, 50, 100, 100);
+ * snapshotView.setFixedSelectionRatio(1); // (this is actually the default value)
+ * snapshotView.setSelectionRatioFixed(true);
+ * </pre>
+ * 
+ * <h3>Functionality Overview</h3>
+ * 
+ * This is just a vague overview. The linked properties provide a more detailed explanation.
+ * 
+ * <h4>Node</h4>
+ * 
+ * The node which this control displays is held by the {@link #nodeProperty() node} property.
+ * 
+ * <h4>Selection</h4>
+ * 
+ * There are several properties which interact to manage and indicate the selection.
+ * 
+ * <h5>State</h5>
+ * <ul>
+ * <li>the selection is held by the {@link #selectionProperty() selection} property
+ * <li>the {@link #hasSelectionProperty() hasSelection} property indicates whether a selection exists
+ * <li>the {@link #selectionActiveProperty() selectionActive} property indicates whether the current selection is active
+ * (it is only displayed if it is); by default this property is updated by this control which is determined by the
+ * {@link #selectionActivityManagedProperty() selectionActivityManaged} property
+ * </ul>
+ * 
+ * <h5>Interaction</h5>
+ * <ul>
+ * <li>if the selection is changing due to the user interacting with the control, this is indicated by the
+ * {@link #selectionChangingProperty() selectionChanging} property
+ * <li>whether the user can select any area of the control or only one above the node is determined by the
+ * {@link #selectionAreaBoundaryProperty() selectionAreaBoundary} property
+ * <li>with the {@link #selectionMouseTransparentProperty() selectionMouseTransparent} property the control can be made
+ * mouse transparent so the user can interact with the displayed node
+ * <li>the selection's ratio of width to height can be fixed with the {@link #selectionRatioFixedProperty()
+ * selectionRatioFixed} and the {@link #fixedSelectionRatioProperty() fixedSelectionRatio} properties
+ * </ul>
+ * 
+ * <h5>Visualization</h5>
+ * <ul>
+ * <li> {@link #selectionAreaFillProperty() selectionAreaFill} property for the selected area's paint
+ * <li> {@link #selectionBorderPaintProperty() selectionBorderPaint} property for the selection border's paint
+ * <li> {@link #selectionBorderWidthProperty() selectionBorderWidth} property for the selection border's width
+ * <li> {@link #unselectedAreaFillProperty() unselectedAreaFill} property for the area outside of the selection
+ * <li> {@link #unselectedAreaBoundaryProperty() unselectedAreaBoundary} property which defined what the unselected area
+ * covers
+ * </ul>
+ */
+public class SnapshotView extends ControlsFXControl {
+
+    /**
+     * The maximal divergence between a selection's ratio and the {@link #fixedSelectionRatioProperty()
+     * fixedselectionRatio} for the selection to still have the correct ratio (see {@link #hasCorrectRatio(Rectangle2D)
+     * hasCorrectRatio}).
+     * <p>
+     * The divergence is expressed relative to the {@code fixedselectionRatio}.
+     */
+    public static final double MAX_SELECTION_RATIO_DIVERGENCE = 1e-6;
+
+    /**
+     * The key of the {@link #getProperties() property} which is used to update {@link #selectionChangingProperty()
+     * selectionChanging}.
+     */
+    public static final String SELECTION_CHANGING_PROPERTY_KEY =
+            SnapshotView.class.getCanonicalName() + ".selection_changing"; //$NON-NLS-1$
+
+    /* ************************************************************************
+     *                                                                         * 
+     * Attributes & Properties                                                 * 
+     *                                                                         * 
+     **************************************************************************/
+
+    // NODE
+
+    /**
+     * @see #nodeProperty()
+     */
+    private final ObjectProperty<Node> node;
+
+    // SELECTION
+
+    /**
+     * @see #selectionProperty()
+     */
+    private final ObjectProperty<Rectangle2D> selection;
+
+    /**
+     * @see #hasSelectionProperty()
+     */
+    private final BooleanProperty hasSelection;
+
+    /**
+     * @see #selectionActiveProperty()
+     */
+    private final BooleanProperty selectionActive;
+
+    /**
+     * @see #selectionChangingProperty()
+     */
+    private final BooleanProperty selectionChanging;
+
+    /**
+     * @see #selectionRatioFixedProperty()
+     */
+    private final BooleanProperty selectionRatioFixed;
+
+    /**
+     * @see #fixedSelectionRatioProperty()
+     */
+    private final DoubleProperty fixedSelectionRatio;
+
+    // META
+
+    /**
+     * @see #selectionAreaBoundaryProperty()
+     */
+    private final ObjectProperty<Boundary> selectionAreaBoundary;
+
+    /**
+     * @see #selectionActivityManagedProperty()
+     */
+    private final BooleanProperty selectionActivityManaged;
+
+    /**
+     * @see #selectionMouseTransparentProperty()
+     */
+    private final BooleanProperty selectionMouseTransparent;
+
+    // VISUALIZATION
+
+    /**
+     * @see #unselectedAreaBoundaryProperty()
+     */
+    private final ObjectProperty<Boundary> unselectedAreaBoundary;
+
+    /**
+     * @see #selectionBorderPaintProperty()
+     */
+    private final ObjectProperty<Paint> selectionBorderPaint;
+
+    /**
+     * @see #selectionBorderWidthProperty()
+     */
+    private final DoubleProperty selectionBorderWidth;
+
+    /**
+     * @see #selectionAreaFillProperty()
+     */
+    private final ObjectProperty<Paint> selectionAreaFill;
+
+    /**
+     * @see #unselectedAreaFillProperty()
+     */
+    private final ObjectProperty<Paint> unselectedAreaFill;
+
+    /* ************************************************************************
+     *                                                                         * 
+     * Construction                                                            * 
+     *                                                                         * 
+     **************************************************************************/
+
+    /**
+     * Creates a new SnapshotView.
+     */
+    public SnapshotView() {
+        getStyleClass().setAll(DEFAULT_STYLE_CLASS);
+
+        // NODE
+        node = new SimpleObjectProperty<>(this, "node"); //$NON-NLS-1$
+
+        // SELECTION
+        selection = new SimpleObjectProperty<Rectangle2D>(this, "selection") { //$NON-NLS-1$
+            @Override
+            public void set(Rectangle2D selection) {
+                if (!isSelectionValid(selection)) {
+                    throw new IllegalArgumentException("The selection \"" + selection + "\" is invalid. " + //$NON-NLS-1$ //$NON-NLS-2$
+                            "Check the comment on 'SnapshotView.selectionProperty()' " + //$NON-NLS-1$
+                            "for all criteria a selection must fulfill."); //$NON-NLS-1$
+                }
+                super.set(selection);
+            }
+        };
+        hasSelection = new SimpleBooleanProperty(this, "hasSelection", false); //$NON-NLS-1$
+        hasSelection.bind(and(isNotNull(selection), notEqual(Rectangle2D.EMPTY, selection)));
+        selectionActive = new SimpleBooleanProperty(this, "selectionActive", false); //$NON-NLS-1$
+        selectionChanging = new SimpleBooleanProperty(this, "selectionChanging", false); //$NON-NLS-1$
+
+        selectionRatioFixed = new SimpleBooleanProperty(this, "selectionRatioFixed", false); //$NON-NLS-1$
+        fixedSelectionRatio = new SimpleDoubleProperty(this, "fixedSelectionRatio", 1) { //$NON-NLS-1$
+            @Override
+            public void set(double newValue) {
+                if (newValue <= 0) {
+                    throw new IllegalArgumentException("The fixed selection ratio must be positive."); //$NON-NLS-1$
+                }
+                super.set(newValue);
+            }
+        };
+
+        // META
+        selectionAreaBoundary = createStylableObjectProperty(
+                this, "selectionAreaBoundary", Boundary.CONTROL, Css.SELECTION_AREA_BOUNDARY); //$NON-NLS-1$
+        selectionActivityManaged = new SimpleBooleanProperty(this, "selectionActivityManaged", true); //$NON-NLS-1$
+        selectionMouseTransparent = new SimpleBooleanProperty(this, "selectionMouseTransparent", false); //$NON-NLS-1$
+
+        // VISUALIZATION
+        unselectedAreaBoundary = createStylableObjectProperty(
+                this, "unselectedAreaBoundary", Boundary.CONTROL, Css.UNSELECTED_AREA_BOUNDARY); //$NON-NLS-1$
+        selectionBorderPaint = createStylableObjectProperty(
+                this, "selectionBorderPaint", Color.WHITESMOKE, Css.SELECTION_BORDER_PAINT); //$NON-NLS-1$
+        selectionBorderWidth = createStylableDoubleProperty(
+                this, "selectionBorderWidth", 2.5, Css.SELECTION_BORDER_WIDTH); //$NON-NLS-1$
+        selectionAreaFill = createStylableObjectProperty(
+                this, "selectionAreaFill", Color.TRANSPARENT, Css.SELECTION_AREA_FILL); //$NON-NLS-1$
+        unselectedAreaFill = createStylableObjectProperty(
+                this, "unselectedAreaFill", new Color(0, 0, 0, 0.5), Css.UNSELECTED_AREA_FILL); //$NON-NLS-1$
+
+        addStateUpdatingListeners();
+        // update selection when resizing
+        new SelectionSizeUpdater().enableResizing();
+    }
+
+    /**
+     * Adds listeners to the properties which update the control's state.
+     */
+    private void addStateUpdatingListeners() {
+        // update the selection activity state when the selection is set
+        selection.addListener((o, oldValue, newValue) -> updateSelectionActivityState());
+
+        // ratio
+        selectionRatioFixed.addListener((o, oldValue, newValue) -> {
+            boolean valueChangedToTrue = !oldValue && newValue;
+            if (valueChangedToTrue) {
+                fixSelectionRatio();
+            }
+        });
+        fixedSelectionRatio.addListener((o, oldValue, newValue) -> {
+            if (isSelectionRatioFixed()) {
+                fixSelectionRatio();
+            }
+        });
+
+        // set selection changing according to the values set in the property map
+        listenToProperty(
+                getProperties(), SELECTION_CHANGING_PROPERTY_KEY, (Boolean value) -> selectionChanging.set(value));
+    }
+
+    /**
+     * Listens to the specified properties. When a pair with the specified key is added, it is processed. If the value
+     * has the correct type, it is given to the specified consumer. Even if the type does not match, it is removed from
+     * the map.
+     * 
+     * @param properties
+     *            the {@link ObservableMap} which contains the properties; typically {@link Control#getProperties()}
+     * @param key
+     *            the key for whose value is listened
+     * @param processValue
+     *            the {@link Consumer} for the new value
+     */
+    private static <T> void listenToProperty(
+            ObservableMap<Object, Object> properties, Object key, Consumer<T> processValue) {
+
+        Objects.requireNonNull(properties, "The argument 'properties' must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(key, "The argument 'key' must not be null."); //$NON-NLS-1$
+        Objects.requireNonNull(processValue, "The argument 'processValue' must not be null."); //$NON-NLS-1$
+
+        @SuppressWarnings("unchecked")
+        MapChangeListener<Object, Object> listener = change -> {
+            boolean addedForKey =
+                    change.wasAdded() && Objects.equals(key, change.getKey());
+            if (addedForKey) {
+                // give the value to the consumer if it has the correct type
+                try {
+                    // note that this cast does nothing except to calm the compiler
+                    // (hence the warning which had to be suppressed)
+                    T newValue = (T) change.getValueAdded();
+                    // this is where the actual exception is created
+                    processValue.accept(newValue);
+                } catch (ClassCastException e) {
+                    // the value was of the wrong type so it can't be processed by the consumer
+                    // -> do nothing
+                }
+                // remove the value from the properties map
+                properties.remove(key);
+            }
+        };
+
+        properties.addListener(listener);
+    }
+
+    /**
+     * Creates a new SnapshotView using the specified node.
+     * 
+     * @param node
+     *            the node to show after construction
+     */
+    public SnapshotView(Node node) {
+        this();
+        setNode(node);
+    }
+
+    /* ************************************************************************
+     *                                                                         * 
+     * Public Methods                                                          * 
+     *                                                                         * 
+     **************************************************************************/
+
+    /**
+     * Transforms the {@link #selectionProperty() selection} to node coordinates by calling
+     * {@link #transformToNodeCoordinates(Rectangle2D) transformToNodeCoordinates}.
+     * 
+     * @return a {@link Rectangle2D} which expresses the selection in the node's coordinates
+     * @throws IllegalStateException
+     *             if {@link #nodeProperty() node} is {@code null} or {@link #hasSelection() hasSelection} is
+     *             {@code false}
+     * @see #transformToNodeCoordinates(Rectangle2D)
+     */
+    public Rectangle2D transformSelectionToNodeCoordinates() {
+        if (!hasSelection()) {
+            throw new IllegalStateException(
+                    "The selection can not be transformed if it does not exist (check 'hasSelection()')."); //$NON-NLS-1$
+        }
+
+        return transformToNodeCoordinates(getSelection());
+    }
+
+    /**
+     * Transforms the specified area's coordinates to coordinates relative to the node. (The node's coordinate system
+     * has its origin in the upper left corner of the node.)
+     * 
+     * @param area
+     *            the {@link Rectangle2D} which will be transformed (must not be {@code null}); its coordinates will be
+     *            interpreted relative to the control (like the {@link #selectionProperty() selection})
+     * @return a {@link Rectangle2D} with the same width and height as the specified {@code area} but with coordinates
+     *         which are relative to the current {@link #nodeProperty() node}
+     * @throws IllegalStateException
+     *             if {@link #nodeProperty() node} is {@code null}
+     */
+    public Rectangle2D transformToNodeCoordinates(Rectangle2D area) throws IllegalStateException {
+        Objects.requireNonNull(area, "The argument 'area' must not be null."); //$NON-NLS-1$
+        if (getNode() == null) {
+            throw new IllegalStateException(
+                    "The selection can not be transformed if the node is null (check 'getNode()')."); //$NON-NLS-1$
+        }
+
+        // get the offset from the node's bounds
+        Bounds nodeBounds = getNode().getBoundsInParent();
+        double xOffset = nodeBounds.getMinX();
+        double yOffset = nodeBounds.getMinY();
+
+        // the coordinates of the transformed selection
+        double minX = area.getMinX() - xOffset;
+        double minY = area.getMinY() - yOffset;
+
+        return new Rectangle2D(minX, minY, area.getWidth(), area.getHeight());
+    }
+
+    /**
+     * Creates a snapshot of the selected area of the node.
+     * 
+     * @return the {@link WritableImage} that holds the rendered selection
+     * @throws IllegalStateException
+     *             if {@link #nodeProperty() node} is {@code null} or {@link #hasSelection() hasSelection} is
+     *             {@code false}
+     * @see Node#snapshot
+     */
+    public WritableImage createSnapshot() throws IllegalStateException {
+        // make sure the node and the selection exist
+        if (getNode() == null) {
+            throw new IllegalStateException("No snapshot can be created if the node is null (check 'getNode()')."); //$NON-NLS-1$
+        }
+        if (!hasSelection()) {
+            throw new IllegalStateException(
+                    "No snapshot can be created if there is no selection (check 'hasSelection()')."); //$NON-NLS-1$
+        }
+
+        SnapshotParameters parameters = new SnapshotParameters();
+        parameters.setViewport(getSelection());
+        return createSnapshot(parameters);
+    }
+
+    /**
+     * Creates a snapshot of the node with the specified parameters.
+     * 
+     * @param parameters
+     *            the {@link SnapshotParameters} used for the snapshot (must not be {@code null}); the viewport will be
+     *            interpreted relative to this control (like the {@link #selectionProperty() selection})
+     * @return the {@link WritableImage} that holds the rendered viewport
+     * @throws IllegalStateException
+     *             if {@link #nodeProperty() node} is {@code null}
+     * @see Node#snapshot
+     */
+    public WritableImage createSnapshot(SnapshotParameters parameters) throws IllegalStateException {
+        // make sure the node and the snapshot parameters exist
+        Objects.requireNonNull(parameters, "The argument 'parameters' must not be null."); //$NON-NLS-1$
+        if (getNode() == null) {
+            throw new IllegalStateException("No snapshot can be created if the node is null (check 'getNode()')."); //$NON-NLS-1$
+        }
+
+        // take the snapshot
+        return getNode().snapshot(parameters, null);
+    }
+
+    /* ************************************************************************
+     *                                                                         * 
+     * Model State                                                             * 
+     *                                                                         * 
+     **************************************************************************/
+
+    /**
+     * Updates the {@link #selectionActiveProperty() selectionActive} property if the
+     * {@link #selectionActivityManagedProperty() selectionActivityManaged} property indicates that it is managed by
+     * this control.
+     */
+    private void updateSelectionActivityState() {
+        boolean userManaged = !isSelectionActivityManaged();
+        if (userManaged) {
+            return;
+        }
+
+        boolean selectionActive = getSelection() != null && getSelection() != Rectangle2D.EMPTY;
+        setSelectionActive(selectionActive);
+    }
+
+    /**
+     * Resizes the current selection (if it exists) to the {@link #fixedSelectionRatioProperty() fixedSelectionRatio}.
+     */
+    private void fixSelectionRatio() {
+        boolean noSelectionToFix = getNode() == null || !hasSelection();
+        if (noSelectionToFix) {
+            return;
+        }
+
+        Rectangle2D selectionBounds = getSelectionBounds();
+        Rectangle2D resizedSelection = Rectangles2D.fixRatioWithinBounds(
+                getSelection(), getFixedSelectionRatio(), selectionBounds);
+
+        selection.set(resizedSelection);
+    }
+
+    /**
+     * 
+     * @return the bounds of the current selection according to the {@link #selectionAreaBoundaryProperty()
+     *         selectionAreaBoundary}.
+     */
+    private Rectangle2D getSelectionBounds() {
+        Boundary boundary = getSelectionAreaBoundary();
+        switch (boundary) {
+        case CONTROL:
+            return new Rectangle2D(0, 0, getWidth(), getHeight());
+        case NODE:
+            return Rectangles2D.fromBounds(getNode().getBoundsInParent());
+        default:
+            throw new IllegalArgumentException("The boundary '" + boundary + "' is not fully implemented yet."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+    }
+
+    /**
+     * Checks whether the specified selection is valid. This includes checking whether the selection is in bounds and
+     * has the correct ratio (if the ratio is fixed).
+     * 
+     * @param selection
+     *            the selection to check as a {@link Rectangle2D}
+     * @return {@code true} if the selection is valid; {@code false} otherwise
+     */
+    private boolean isSelectionValid(Rectangle2D selection) {
+        // empty selections are valid
+        boolean emptySelection = selection == null || selection == Rectangle2D.EMPTY;
+        if (emptySelection) {
+            return true;
+        }
+
+        // check values
+        if (!valuesFinite(selection)) {
+            return false;
+        }
+
+        // check bounds
+        if (!inBounds(selection)) {
+            return false;
+        }
+
+        // check ratio
+        if (!hasCorrectRatio(selection)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Indicates whether the specified selection has only finite values (e.g. width and height).
+     * 
+     * @param selection
+     *            the selection as a {@link Rectangle2D}
+     * @return {@code true} if the selection has only finite values.
+     */
+    private static boolean valuesFinite(Rectangle2D selection) {
+        return Double.isFinite(selection.getMinX()) && Double.isFinite(selection.getMinY()) &&
+                Double.isFinite(selection.getWidth()) && Double.isFinite(selection.getHeight());
+    }
+
+    /**
+     * Indicates whether the specified selection is inside the bounds determined by the
+     * {@link #selectionAreaBoundaryProperty() selectionAreaBoundary} property.
+     * 
+     * @param selection
+     *            the non-null and non-empty selection as a {@link Rectangle2D}
+     * @return {@code true} if the selection is fully contained in the bounds; otherwise {@code false}
+     */
+    private boolean inBounds(Rectangle2D selection) {
+        Boundary boundary = getSelectionAreaBoundary();
+        switch (boundary) {
+        case CONTROL:
+            return inBounds(selection, getBoundsInLocal());
+        case NODE:
+            if (getNode() == null) {
+                return false;
+            } else {
+                return inBounds(selection, getNode().getBoundsInParent());
+            }
+        default:
+            throw new IllegalArgumentException("The boundary '" + boundary + "' is not fully implemented yet."); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+    }
+
+    /**
+     * Indicates whether the specified selection is inside the specified bounds.
+     * 
+     * @param selection
+     *            the selection as a {@link Rectangle2D}
+     * @param bounds
+     *            the {@link Bounds} to check the selection against
+     * @return {@code true} if the selection is fully contained in the bounds; otherwise {@code false}
+     */
+    private static boolean inBounds(Rectangle2D selection, Bounds bounds) {
+        return bounds.getMinX() <= selection.getMinX() && bounds.getMinY() <= selection.getMinY() &&
+                selection.getMaxX() <= bounds.getMaxX() && selection.getMaxY() <= bounds.getMaxY();
+    }
+
+    /**
+     * Indicates whether the specified selection has the correct ratio (which depends on whether the ratio is even
+     * {@link #selectionRatioFixedProperty() fixed}).
+     * 
+     * @param selection
+     *            the selection to check as a {@link Rectangle2D}
+     * @return {@code true} if the selection has the correct ratio.
+     */
+    private boolean hasCorrectRatio(Rectangle2D selection) {
+        if (!isSelectionRatioFixed()) {
+            return true;
+        }
+
+        double ratio = selection.getWidth() / selection.getHeight();
+        // compute the divergence relative to the fixed selection ratio
+        double ratioDivergence = Math.abs(1 - ratio / getFixedSelectionRatio());
+        return ratioDivergence <= MAX_SELECTION_RATIO_DIVERGENCE;
+    }
+
+    /* ************************************************************************
+     *                                                                         * 
+     * Style Sheet & Skin Handling                                             * 
+     *                                                                         * 
+     **************************************************************************/
+
+    /**
+     * The name of the style class used in CSS for instances of this class.
+     */
+    private static final String DEFAULT_STYLE_CLASS = "snapshot-view"; //$NON-NLS-1$
+
+    /** {@inheritDoc} */
+    @Override
+    public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(SnapshotView.class, "snapshot-view.css"); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates a {@link StyleableDoubleProperty} with the specified arguments.
+     * 
+     * @param bean
+     *            the {@link Property#getBean() bean} the created property belongs to
+     * @param name
+     *            the property's {@link Property#getName() name}
+     * @param initialValue
+     *            the property's initial value
+     * @param cssMetaData
+     *            the {@link CssMetaData} for the created property
+     * @return a {@link StyleableDoubleProperty}
+     */
+    private static StyleableDoubleProperty createStylableDoubleProperty(
+            Object bean, String name, double initialValue, CssMetaData<? extends Styleable, Number> cssMetaData) {
+
+        return new StyleableDoubleProperty(initialValue) {
+
+            @Override
+            public Object getBean() {
+                return bean;
+            }
+
+            @Override
+            public String getName() {
+                return name;
+            }
+
+            @Override
+            public CssMetaData<? extends Styleable, Number> getCssMetaData() {
+                return cssMetaData;
+            }
+
+        };
+    }
+
+    /**
+     * Creates a {@link StyleableObjectProperty} with the specified arguments.
+     * 
+     * @param bean
+     *            the {@link Property#getBean() bean} the created property belongs to
+     * @param name
+     *            the property's {@link Property#getName() name}
+     * @param initialValue
+     *            the property's initial value
+     * @param cssMetaData
+     *            the {@link CssMetaData} for the created property
+     * @return a {@link StyleableObjectProperty}
+     */
+    private static <T> StyleableObjectProperty<T> createStylableObjectProperty(
+            Object bean, String name, T initialValue, CssMetaData<? extends Styleable, T> cssMetaData) {
+
+        return new StyleableObjectProperty<T>(initialValue) {
+
+            @Override
+            public Object getBean() {
+                return bean;
+            }
+
+            @Override
+            public String getName() {
+                return name;
+            }
+
+            @Override
+            public CssMetaData<? extends Styleable, T> getCssMetaData() {
+                return cssMetaData;
+            }
+
+        };
+    }
+
+    /**
+     * Creates an instance of {@link CssMetaData} with the specified arguments.
+     * 
+     * @param getProperty
+     *            a function from the {@link Styleable} which owns the styled property to the property styled by the
+     *            returned {@code CssMetaData}
+     * @param cssPropertyName
+     *            the name by which the styled property is referenced in CSS files
+     * @param styleConverter
+     *            the {@link StyleConverter} used to convert the CSS parsed value to a Java object
+     * @return an instance of {@link CssMetaData}
+     */
+    private static <S extends Styleable, T> CssMetaData<S, T> createCssMetaData(
+            Function<S, Property<T>> getProperty, String cssPropertyName, StyleConverter<?, T> styleConverter) {
+
+        return new CssMetaData<S, T>(cssPropertyName, styleConverter) {
+
+            @Override
+            public boolean isSettable(S styleable) {
+                final Property<T> property = getProperty.apply(styleable);
+                return property != null && !property.isBound();
+            }
+
+            @Override
+            @SuppressWarnings("unchecked")
+            public StyleableProperty<T> getStyleableProperty(S styleable) {
+                return (StyleableProperty<T>) getProperty.apply(styleable);
+            }
+        };
+    }
+
+    /**
+     * The class which holds this control's {@link CssMetaData} for the different {@link StyleableProperty
+     * StyleableProperties}.
+     */
+    @SuppressWarnings({ "javadoc", "unchecked" })
+    private static class Css {
+
+        public static final CssMetaData<SnapshotView, Boundary> SELECTION_AREA_BOUNDARY =
+                createCssMetaData(
+                        snapshotView -> snapshotView.selectionAreaBoundary, "-fx-selection-area-boundary", //$NON-NLS-1$
+                        (StyleConverter<?, Boundary>) StyleConverter.getEnumConverter(Boundary.class));
+
+        public static final CssMetaData<SnapshotView, Boundary> UNSELECTED_AREA_BOUNDARY =
+                createCssMetaData(
+                        snapshotView -> snapshotView.unselectedAreaBoundary, "-fx-unselected-area-boundary", //$NON-NLS-1$
+                        (StyleConverter<?, Boundary>) StyleConverter.getEnumConverter(Boundary.class));
+
+        public static final CssMetaData<SnapshotView, Paint> SELECTION_BORDER_PAINT =
+                createCssMetaData(
+                        snapshotView -> snapshotView.selectionBorderPaint, "-fx-selection-border-paint", //$NON-NLS-1$
+                        StyleConverter.getPaintConverter());
+
+        public static final CssMetaData<SnapshotView, Number> SELECTION_BORDER_WIDTH =
+                createCssMetaData(
+                        snapshotView -> snapshotView.selectionBorderWidth, "-fx-selection-border-width", //$NON-NLS-1$
+                        StyleConverter.getSizeConverter());
+
+        public static final CssMetaData<SnapshotView, Paint> SELECTION_AREA_FILL =
+                createCssMetaData(
+                        snapshotView -> snapshotView.selectionAreaFill, "-fx-selection-area-fill", //$NON-NLS-1$
+                        StyleConverter.getPaintConverter());
+
+        public static final CssMetaData<SnapshotView, Paint> UNSELECTED_AREA_FILL =
+                createCssMetaData(
+                        snapshotView -> snapshotView.unselectedAreaFill, "-fx-unselected-area-fill", //$NON-NLS-1$
+                        StyleConverter.getPaintConverter());
+
+        /**
+         * The {@link CssMetaData} associated with this class, which includes the {@code CssMetaData} of its super
+         * classes.
+         */
+        public static final List<CssMetaData<? extends Styleable, ?>> CSS_META_DATA;
+
+        static {
+            final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData());
+            styleables.add(SELECTION_AREA_BOUNDARY);
+            styleables.add(UNSELECTED_AREA_BOUNDARY);
+            styleables.add(SELECTION_BORDER_PAINT);
+            styleables.add(SELECTION_BORDER_WIDTH);
+            styleables.add(SELECTION_AREA_FILL);
+            styleables.add(UNSELECTED_AREA_FILL);
+            CSS_META_DATA = Collections.unmodifiableList(styleables);
+        }
+    }
+
+    /**
+     * @return the {@link CssMetaData} associated with this class, which includes the {@code CssMetaData} of its super
+     *         classes
+     */
+    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
+        return Css.CSS_META_DATA;
+    }
+
+    @Override
+    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
+        return getClassCssMetaData();
+    }
+
+    @Override
+    protected Skin<?> createDefaultSkin() {
+        return new SnapshotViewSkin(this);
+    }
+
+    /* ************************************************************************
+     *                                                                         * 
+     * Property Access                                                         * 
+     *                                                                         * 
+     **************************************************************************/
+
+    // NODE
+
+    /**
+     * The {@link Node} which will be displayed in the center of this control.
+     * <p>
+     * The node's {@link Node#boundsInParentProperty() boundsInParent} show its relative position inside this control.
+     * Since the {@link #selectionProperty() selection} property also uses this control as its reference coordinate
+     * system, the bounds can be used to compute which area of the node is selected.
+     * <p>
+     * If this control or the node behaves strangely when resized, try embedding the original node in a {@link Pane} and
+     * setting the pane here.
+     * 
+     * @return the property holding the displayed node
+     */
+    public final ObjectProperty<Node> nodeProperty() {
+        return node;
+    }
+
+    /**
+     * @return the displayed node
+     * @see #nodeProperty()
+     */
+    public final Node getNode() {
+        return nodeProperty().get();
+    }
+
+    /**
+     * @param node
+     *            the node to display
+     * @see #nodeProperty()
+     */
+    public final void setNode(Node node) {
+        nodeProperty().set(node);
+    }
+
+    // SELECTION
+
+    /**
+     * The current selection as a {@link Rectangle2D}. As such an instance is immutable a new one must be set to chane
+     * the selection.
+     * <p>
+     * The rectangle's coordinates are interpreted relative to this control. The top left corner is the origin (0, 0)
+     * and the lower right corner is ({@link #widthProperty() width}, {@link #heightProperty() height}). It is
+     * guaranteed that the selection always lies within these bounds. If the control is resized, so is the selection. If
+     * a selection which violates these bounds is set, an {@link IllegalArgumentException} is thrown.
+     * <p>
+     * The same is true if the {@link #selectionAreaBoundaryProperty() selectionAreaBoundary} is set to {@code NODE} but
+     * with the stricter condition that the selection must lie within the {@link #nodeProperty() node}'s
+     * {@link Node#boundsInParentProperty() boundsInParent}.
+     * <p>
+     * If the selection ratio is {@link #selectionRatioFixedProperty() fixed}, any new selection must have the
+     * {@link #fixedSelectionRatioProperty() fixedSelectionRatio}. Otherwise, an {@code IllegalArgumentException} is
+     * thrown.
+     * <p>
+     * An {@code IllegalArgumentException} is also thrown if not all of the selection's values (e.g. width and height)
+     * are finite.
+     * <p>
+     * The selection might be {@code null} or {@link Rectangle2D#EMPTY} in which case no selection is displayed and
+     * {@link #hasSelectionProperty() hasSelection} is {@code false}.
+     * 
+     * @return the property holding the current selection
+     * @see #hasSelectionProperty()
+     */
+    public final ObjectProperty<Rectangle2D> selectionProperty() {
+        return selection;
+    }
+
+    /**
+     * @return the current selection
+     * @see #selectionProperty()
+     */
+    public final Rectangle2D getSelection() {
+        return selectionProperty().get();
+    }
+
+    /**
+     * @param selection
+     *            the new selection
+     * @throws IllegalArgumentException
+     *             if the selection is out of the bounds defined by the {@link #selectionAreaBoundaryProperty()
+     *             selectionAreaBoundary} or the selection ratio is {@link #selectionRatioFixedProperty() fixed} and the
+     *             new selection does not have the {@link #fixedSelectionRatioProperty() fixedSelectionRatio}.
+     * @see #selectionProperty()
+     */
+    public final void setSelection(Rectangle2D selection) {
+        selectionProperty().set(selection);
+    }
+
+    /**
+     * Creates a new {@link Rectangle2D} from the specified arguments and sets it as the new
+     * {@link #selectionProperty() selection}. It will have ({@code upperLeftX}, {@code upperLeftY}) as its upper left
+     * point and span {@code width} to the right and {@code height} down.
+     * 
+     * @param upperLeftX
+     *            the x coordinate of the selection's upper left point
+     * @param upperLeftY
+     *            the y coordinate of the selection's upper left point
+     * @param width
+     *            the selection's width
+     * @param height
+     *            the selection's height
+     * @throws IllegalArgumentException
+     *             if the selection is out of the bounds defined by the {@link #selectionAreaBoundaryProperty()
+     *             selectionAreaBoundary} or the selection ratio is {@link #selectionRatioFixedProperty() fixed} and the
+     *             new selection does not have the {@link #fixedSelectionRatioProperty() fixedSelectionRatio}.
+     * @see #selectionProperty()
+     * 
+     */
+    public final void setSelection(double upperLeftX, double upperLeftY, double width, double height) {
+        selectionProperty().set(new Rectangle2D(upperLeftX, upperLeftY, width, height));
+    }
+
+    /**
+     * Indicates whether there currently is a selection. This will be {@code false} if the {@link #selectionProperty()
+     * selection} property holds {@code null} or {@link Rectangle2D#EMPTY} .
+     * 
+     * @return a property indicating whether there currently is a selection
+     */
+    public final ReadOnlyBooleanProperty hasSelectionProperty() {
+        return hasSelection;
+    }
+
+    /**
+     * @return whether there currently is a selection
+     * @see #hasSelectionProperty()
+     */
+    public final boolean hasSelection() {
+        return hasSelectionProperty().get();
+    }
+
+    /**
+     * Indicates whether the selection is currently active. Only an active selection will be displayed by the control.
+     * <p>
+     * See {@link #selectionActivityManagedProperty() selectionActivityManaged} for documentation on how this property
+     * might be changed by this control.
+     * 
+     * @return the property indicating whether the selection is active
+     */
+    public final BooleanProperty selectionActiveProperty() {
+        return selectionActive;
+    }
+
+    /**
+     * @return whether the selection is active
+     * @see #selectionActiveProperty()
+     */
+    public final boolean isSelectionActive() {
+        return selectionActiveProperty().get();
+    }
+
+    /**
+     * @param selectionActive
+     *            the new selection active status
+     * @see #selectionActiveProperty()
+     */
+    public final void setSelectionActive(boolean selectionActive) {
+        selectionActiveProperty().set(selectionActive);
+    }
+
+    /**
+     * Indicates whether the {@link #selectionProperty() selection} is currently changing due to user interaction with
+     * the control. It will be set to {@code true} when changing the selection begins and set to {@code false} when it
+     * ends.
+     * <p>
+     * If a selection is set by the code using this control (e.g. by calling {@link #setSelection(Rectangle2D)
+     * setSelection}) this property does not change its value.
+     * 
+     * @return a property indicating whether the selection is changing by user interaction
+     */
+    public final ReadOnlyBooleanProperty selectionChangingProperty() {
+        return selectionChanging;
+    }
+
+    /**
+     * @return whether the selection is changing by user interaction
+     * @see #selectionChangingProperty()
+     */
+    public final boolean isSelectionChanging() {
+        return selectionChangingProperty().get();
+    }
+
+    /**
+     * Indicates whether the ratio of the {@link #selectionProperty() selection} is fixed.
+     * <p>
+     * By default this property is {@code false} and the user interacting with this control can make arbitrary
+     * selections with any ratio of width to height. If it is {@code true}, the user is limited to making selections
+     * with the ratio defined by the {@link #fixedSelectionRatioProperty() fixedSelectionRatio} property. If the ratio
+     * is fixed and a selection with a different ratio is set, an {@link IllegalArgumentException} is thrown.
+     * <p>
+     * If a selection exists and this property is set to {@code true}, the selection is immediately resized to the
+     * currently set ratio.
+     * 
+     * @defaultValue {@code false}
+     * @return the property indicating whether the selection ratio is fixed
+     */
+    public final BooleanProperty selectionRatioFixedProperty() {
+        return selectionRatioFixed;
+    }
+
+    /**
+     * @return whether the selection ratio is fixed
+     * @see #selectionRatioFixedProperty()
+     */
+    public final boolean isSelectionRatioFixed() {
+        return selectionRatioFixedProperty().get();
+    }
+
+    /**
+     * @param selectionRatioFixed
+     *            whether the selection ratio will be fixed
+     * @see #selectionRatioFixedProperty()
+     */
+    public final void setSelectionRatioFixed(boolean selectionRatioFixed) {
+        selectionRatioFixedProperty().set(selectionRatioFixed);
+    }
+
+    /**
+     * The value to which the selection ratio is fixed. The ratio is defined as {@code width / height} and its value
+     * must be strictly positive.
+     * <p>
+     * If {@link #selectionRatioFixedProperty() selectionRatioFixed} is {@code true}, this ratio will be upheld by all
+     * changes made by user interaction with this control. If the ratio is fixed and a selection is set by code (e.g. by
+     * calling {@link #setSelection(Rectangle2D) setSelection}), this ratio is checked and if violated an
+     * {@link IllegalArgumentException} is thrown.
+     * <p>
+     * If a selection exists and {@code selectionRatioFixed} is set to {@code true}, the selection is immediately
+     * resized to this ratio. Similarly, if a selection exists and its ratio is fixed, setting a new value resizes the
+     * selection to the new ratio.
+     * 
+     * @defaultValue 1.0
+     * @return a property containing the fixed selection ratio
+     */
+    public final DoubleProperty fixedSelectionRatioProperty() {
+        return fixedSelectionRatio;
+    }
+
+    /**
+     * @return the fixedSelectionRatio, which will always be a strictly positive value
+     * @see #fixedSelectionRatioProperty()
+     */
+    public final double getFixedSelectionRatio() {
+        return fixedSelectionRatioProperty().get();
+    }
+
+    /**
+     * @param fixedSelectionRatio
+     *            the fixed selection ratio to set
+     * @throws IllegalArgumentException
+     *             if {@code fixedSelectionRatio} is not strictly positive
+     * @see #fixedSelectionRatioProperty()
+     */
+    public final void setFixedSelectionRatio(double fixedSelectionRatio) {
+        fixedSelectionRatioProperty().set(fixedSelectionRatio);
+    }
+
+    // META
+
+    /**
+     * Indicates which {@link Boundary} is set for the area the user can select.
+     * <p>
+     * By default the user can select any area of the control. If this should be limited to the area over the displayed
+     * node instead, this property can be set to {@link Boundary#NODE NODE}. If the value is changed from
+     * {@code CONTROL} to {@code NODE} a possibly existing selection is resized accordingly.
+     * <p>
+     * If the boundary is set to {@code NODE}, this is also respected when a new {@link #selectionProperty() selection}
+     * is set. This means the condition for the new selection's coordinates is made stricter and setting a selection out
+     * of the node's bounds (instead of only out of the control's bounds) throws an {@link IllegalArgumentException}.
+     * <p>
+     * Note that this does <b>not</b> change the reference coordinate system! The selection's coordinates are still
+     * interpreted relative to the {@link #nodeProperty() node}'s {@link Node#boundsInParentProperty() boundsInParent}.
+     * 
+     * @defaultValue {@link Boundary#CONTROL CONTROL}
+     * @return the property indicating the {@link Boundary} for the area the user can select
+     */
+    public final ObjectProperty<Boundary> selectionAreaBoundaryProperty() {
+        return selectionAreaBoundary;
+    }
+
+    /**
+     * @return the {@link Boundary} for the area the user can select
+     */
+    public final Boundary getSelectionAreaBoundary() {
+        return selectionAreaBoundaryProperty().get();
+    }
+
+    /**
+     * @param selectionAreaBoundary
+     *            the new {@link Boundary} for the area the user can select
+     */
+    public final void setSelectionAreaBoundary(Boundary selectionAreaBoundary) {
+        selectionAreaBoundaryProperty().set(selectionAreaBoundary);
+    }
+
+    /**
+     * Indicates whether the value of the {@link #selectionActiveProperty() selectionActive} property is managed by this
+     * control.
+     * <p>
+     * If this property is set to {@code true} (which is the default) this control will update the
+     * {@code selectionActive} property immediately after a new selection is set: if the new selection is {@code null}
+     * or {@link Rectangle2D#EMPTY}, it will be set to {@code false}; otherwise to {@code true}.
+     * <p>
+     * If this property is {@code false} this control will never change {@code selectionActive}'s value. In this case it
+     * must be managed by the using code but it is possible to unidirectionally bind it to another property without this
+     * control interfering.
+     * 
+     * @defaultValue {@code true}
+     * @return the property indicating whether the value of the {@link #selectionActiveProperty() selectionActive}
+     *         property is managed by this control
+     */
+    public final BooleanProperty selectionActivityManagedProperty() {
+        return selectionActivityManaged;
+    }
+
+    /**
+     * @return whether the selection activity is managed by this control
+     * @see #selectionActivityManagedProperty()
+     */
+    public final boolean isSelectionActivityManaged() {
+        return selectionActivityManagedProperty().get();
+    }
+
+    /**
+     * @param selectionActivityManaged
+     *            whether the selection activity will be managed by this control
+     * @see #selectionActivityManagedProperty()
+     */
+    public final void setSelectionActivityManaged(boolean selectionActivityManaged) {
+        selectionActivityManagedProperty().set(selectionActivityManaged);
+    }
+
+    /**
+     * Indicates whether the overlay which displays the selection is mouse transparent.
+     * <p>
+     * By default all mouse events are captured by this control and used to interact with the selection. If this
+     * property is set to {@code true}, this behavior changes and the user is able to interact with the displayed
+     * {@link #nodeProperty() node}.
+     * 
+     * @defaultValue {@code false}
+     * @return the property indicating whether the selection is mouse transparent
+     */
+    public final BooleanProperty selectionMouseTransparentProperty() {
+        return selectionMouseTransparent;
+    }
+
+    /**
+     * @return whether the selection is mouse transparent
+     * @see #selectionMouseTransparentProperty()
+     */
+    public final boolean isSelectionMouseTransparent() {
+        return selectionMouseTransparentProperty().get();
+    }
+
+    /**
+     * @param selectionMouseTransparent
+     *            whether the selection will be mouse transparent
+     * @see #selectionMouseTransparentProperty()
+     */
+    public final void setSelectionMouseTransparent(boolean selectionMouseTransparent) {
+        selectionMouseTransparentProperty().set(selectionMouseTransparent);
+    }
+
+    // VISUALIZATION
+
+    /**
+     * Indicates which {@link Boundary} is set for the visualization of the unselected area (i.e. the area outside of
+     * the selection rectangle).
+     * <p>
+     * If it is set to {@link Boundary#CONTROL CONTROL} (which is the default), the unselected area covers the whole
+     * control.
+     * <p>
+     * If it is set to {@link Boundary#NODE NODE}, the area only covers the displayed {@link #nodeProperty() node}. In
+     * most cases this only makes sense if the {@link #selectionAreaBoundaryProperty() selectionAreaBoundary} is also
+     * set to {@code NODE}.
+     * 
+     * @defaultValue {@link Boundary#CONTROL}
+     * @return the property defining the {@link Boundary} of the unselected area
+     */
+    public final ObjectProperty<Boundary> unselectedAreaBoundaryProperty() {
+        return unselectedAreaBoundary;
+    }
+
+    /**
+     * @return the {@link Boundary} for the unselected area
+     * @see #unselectedAreaBoundaryProperty()
+     */
+    public final Boundary getUnselectedAreaBoundary() {
+        return unselectedAreaBoundaryProperty().get();
+    }
+
+    /**
+     * @param unselectedAreaBoundary
+     *            the new {@link Boundary} for the unselected area
+     * @see #unselectedAreaBoundaryProperty()
+     */
+    public final void setUnselectedAreaBoundary(Boundary unselectedAreaBoundary) {
+        unselectedAreaBoundaryProperty().set(unselectedAreaBoundary);
+    }
+
+    /**
+     * Determines the visualization of the selection's border.
+     * 
+     * @defaultValue {@link Color#WHITESMOKE}
+     * @return the property holding the {@link Paint} of the selection border
+     * @see #selectionBorderWidthProperty()
+     */
+    public final ObjectProperty<Paint> selectionBorderPaintProperty() {
+        return selectionBorderPaint;
+    }
+
+    /**
+     * @return the {@link Paint} of the selection border
+     * @see #selectionBorderPaintProperty()
+     */
+    public final Paint getSelectionBorderPaint() {
+        return selectionBorderPaintProperty().get();
+    }
+
+    /**
+     * @param selectionBorderPaint
+     *            the new {@link Paint} of the selection border
+     * @see #selectionBorderPaintProperty()
+     */
+    public final void setSelectionBorderPaint(Paint selectionBorderPaint) {
+        selectionBorderPaintProperty().set(selectionBorderPaint);
+    }
+
+    /**
+     * Determines the width of the selection's border. The border is always painted to the outside of the selected area,
+     * i.e. the selected area is never covered by the border.
+     * 
+     * @defaultValue 2.5
+     * @return the property defining the selection border's width
+     * @see #selectionBorderPaintProperty()
+     * @see javafx.scene.shape.Shape#strokeWidthProperty() Shape.strokeWidthProperty()
+     */
+    public final DoubleProperty selectionBorderWidthProperty() {
+        return selectionBorderWidth;
+    }
+
+    /**
+     * @return the selection border width
+     * @see #selectionBorderWidthProperty()
+     */
+    public final double getSelectionBorderWidth() {
+        return selectionBorderWidthProperty().get();
+    }
+
+    /**
+     * @param selectionBorderWidth
+     *            the selection border width to set
+     * @see #selectionBorderWidthProperty()
+     */
+    public final void setSelectionBorderWidth(double selectionBorderWidth) {
+        selectionBorderWidthProperty().set(selectionBorderWidth);
+    }
+
+    /**
+     * Determines the visualization of the selected area.
+     * 
+     * @defaultValue {@link Color#TRANSPARENT}
+     * @return the property holding the {@link Paint} of the selected area
+     */
+    public final ObjectProperty<Paint> selectionAreaFillProperty() {
+        return selectionAreaFill;
+    }
+
+    /**
+     * @return the {@link Paint} of the selected area
+     * @see #selectionAreaFillProperty()
+     */
+    public final Paint getSelectionAreaFill() {
+        return selectionAreaFillProperty().get();
+    }
+
+    /**
+     * @param selectionAreaFill
+     *            the new {@link Paint} of the selected area
+     * @see #selectionAreaFillProperty()
+     */
+    public final void setSelectionAreaFill(Paint selectionAreaFill) {
+        selectionAreaFillProperty().set(selectionAreaFill);
+    }
+
+    /**
+     * Determines the visualization of the area outside of the selection.
+     * 
+     * @defaultValue {@link Color#BLACK black} with {@link Color#getOpacity() opacity} 0.5
+     * @return the property holding the {@link Paint} of the area outside of the selection
+     */
+    public final ObjectProperty<Paint> unselectedAreaFillProperty() {
+        return unselectedAreaFill;
+    }
+
+    /**
+     * @return the {@link Paint} of the area outside of the selection
+     * @see #unselectedAreaFillProperty()
+     */
+    public final Paint getUnselectedAreaFill() {
+        return unselectedAreaFillProperty().get();
+    }
+
+    /**
+     * @param unselectedAreaFill
+     *            the new {@link Paint} of the area outside of the selection
+     * @see #unselectedAreaFillProperty()
+     */
+    public final void setUnselectedAreaFill(Paint unselectedAreaFill) {
+        unselectedAreaFillProperty().set(unselectedAreaFill);
+    }
+
+    /* ************************************************************************
+     *                                                                         *
+     * Inner Classes                                                           *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * The {@link SnapshotView#selectionAreaBoundaryProperty() selectionArea}, in which the user can create a selection,
+     * and the {@link SnapshotView#unselectedAreaBoundaryProperty() unselectedArea}, in which the unselected area is
+     * visualized, are limited to a certain area of the control. This area's boundary is represented by this enum.
+     *
+     */
+    public static enum Boundary {
+
+        /**
+         * The boundary is this control's bound.
+         */
+        CONTROL,
+
+        /**
+         * The boundary is the displayed node's bound.
+         */
+        NODE,
+
+    }
+
+    /**
+     * Updates the size of the {@link SnapshotView#selectionProperty() selection} whenever necessary. This is the case
+     * if the {@link SnapshotView#selectionAreaBoundaryProperty() selectionAreaBoundary} is set to
+     * {@link Boundary#CONTROL CONTROL} and the control is resized or when it is set to {@link Boundary#NODE NODE} and
+     * the node is changed or resized.
+     *
+     */
+    private class SelectionSizeUpdater {
+
+        /*
+         * If the 'selectionAreaBoundary' is set to 'CONTROL', the selection is only updated when the control changes
+         * its width or height. If it is set to 'NODE', the selection is resized whenever the node or its
+         * 'boundsInParent' change.
+         * For both cases methods exist which resize the selection. The listeners which call those methods are only
+         * added to the corresponding properties when the matching boundary is selected.
+         */
+
+        // CONTROL
+
+        /**
+         * Calls {@link #resizeSelectionToNewControlWidth(ObservableValue, Number, Number)
+         * updateSelectionToNewControlWidth} whenever the control's width changes.
+         */
+        private final ChangeListener<Number> resizeSelectionToNewControlWidthListener;
+
+        /**
+         * Calls {@link #resizeSelectionToNewControlHeight(ObservableValue, Number, Number)
+         * updateSelectionToNewControlWidth} whenever the control's height changes.
+         */
+        private final ChangeListener<Number> resizeSelectionToNewControlHeightListener;
+
+        // NODE
+
+        /**
+         * Calls {@link #updateSelectionToNewNode(ObservableValue, Node, Node) updateSelectionToNewNode} whenever a new
+         * {@link SnapshotView#nodeProperty() node} is set.
+         */
+        private final ChangeListener<Node> updateSelectionToNodeListener;
+
+        /**
+         * Calls {@link #resizeSelectionToNewNodeBounds(ObservableValue, Bounds, Bounds) updateSelectionToNewNodeBounds}
+         * whenever the node's {@link Node#boundsInParentProperty() boundsInParent} change.
+         */
+        private final ChangeListener<Bounds> resizeSelectionToNewNodeBoundsListener;
+
+        // CONSTRUCTION
+
+        /**
+         * Creates a new selection size updater.
+         */
+        public SelectionSizeUpdater() {
+            // create listeners which point to methods
+            resizeSelectionToNewControlWidthListener = this::resizeSelectionToNewControlWidth;
+            resizeSelectionToNewControlHeightListener = this::resizeSelectionToNewControlHeight;
+            updateSelectionToNodeListener = this::updateSelectionToNewNode;
+            resizeSelectionToNewNodeBoundsListener = this::resizeSelectionToNewNodeBounds;
+        }
+
+        // ENABLE RESIZING
+
+        /**
+         * Enables resizing of the control.
+         */
+        public void enableResizing() {
+            // only resize if the selection is not null
+            enableResizingForBoundary(getSelectionAreaBoundary());
+            selectionAreaBoundary.addListener((o, oldBoundary, newBoundary) -> enableResizingForBoundary(newBoundary));
+        }
+
+        /**
+         * Enables resizing for the specified boundary.
+         * 
+         * @param boundary
+         *            the {@link Boundary} for which the control will be resized.
+         */
+        private void enableResizingForBoundary(Boundary boundary) {
+            switch (boundary) {
+            case CONTROL:
+                enableResizingForControl();
+                break;
+            case NODE:
+                enableResizingForNode();
+                break;
+            default:
+                throw new IllegalArgumentException("The boundary '" + boundary + "' is not fully implemented yet."); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+        }
+
+        /**
+         * Enables resizing if the {@link SnapshotView#selectionAreaBoundary selectionAreaBoundary} is
+         * {@link Boundary#CONTROL CONTROL}.
+         */
+        private void enableResizingForControl() {
+            // remove listeners for node and its bounds
+            node.removeListener(updateSelectionToNodeListener);
+            if (getNode() != null) {
+                getNode().boundsInParentProperty().removeListener(resizeSelectionToNewNodeBoundsListener);
+            }
+
+            // add listener for the control's size
+            widthProperty().addListener(resizeSelectionToNewControlWidthListener);
+            heightProperty().addListener(resizeSelectionToNewControlHeightListener);
+
+            resizeSelectionFromNodeToControl();
+        }
+
+        /**
+         * Enables resizing if the {@link SnapshotView#selectionAreaBoundary selectionAreaBoundary} is
+         * {@link Boundary#NODE NODE}.
+         */
+        private void enableResizingForNode() {
+            // remove listeners for the control's size
+            widthProperty().removeListener(resizeSelectionToNewControlWidthListener);
+            heightProperty().removeListener(resizeSelectionToNewControlHeightListener);
+
+            // add listener for the node's bounds and for new nodes
+            if (getNode() != null) {
+                getNode().boundsInParentProperty().addListener(resizeSelectionToNewNodeBoundsListener);
+            }
+            node.addListener(updateSelectionToNodeListener);
+
+            resizeSelectionFromControlToNode();
+        }
+
+        // RESIZE TO CONTROL
+
+        /**
+         * Resizes the current {@link SnapshotView#selectionProperty() selection} from the node's to the control's
+         * bounds.
+         */
+        private void resizeSelectionFromNodeToControl() {
+            if (getNode() == null) {
+                setSelection(null);
+            } else {
+                // transform the selection from the control's to the node's bounds
+                Rectangle2D controlBounds = new Rectangle2D(0, 0, getWidth(), getHeight());
+                Rectangle2D nodeBounds = Rectangles2D.fromBounds(getNode().getBoundsInParent());
+                resizeSelectionToNewBounds(nodeBounds, controlBounds);
+            }
+        }
+
+        /**
+         * Resizes the current {@link SnapshotView#selectionProperty() selection} from the control's specified old width
+         * to its specified new width.
+         * <p>
+         * Designed to be used as a lambda method reference.
+         * 
+         * @param o
+         *            the {@link ObservableValue} which changed its value
+         * @param oldWidth
+         *            the control's old width
+         * @param newWidth
+         *            the control's new width
+         */
+        private void resizeSelectionToNewControlWidth(
+                @SuppressWarnings("unused") ObservableValue<? extends Number> o, Number oldWidth, Number newWidth) {
+
+            Rectangle2D oldBounds = new Rectangle2D(0, 0, oldWidth.doubleValue(), getHeight());
+            Rectangle2D newBounds = new Rectangle2D(0, 0, newWidth.doubleValue(), getHeight());
+            resizeSelectionToNewBounds(oldBounds, newBounds);
+        }
+
+        /**
+         * Resizes the current {@link SnapshotView#selectionProperty() selection} from the control's specified old
+         * height to its specified new height.
+         * <p>
+         * Designed to be used as a lambda method reference.
+         * 
+         * @param o
+         *            the {@link ObservableValue} which changed its value
+         * @param oldHeight
+         *            the control's old height
+         * @param newHeight
+         *            the control's new height
+         */
+        private void resizeSelectionToNewControlHeight(
+                @SuppressWarnings("unused") ObservableValue<? extends Number> o, Number oldHeight, Number newHeight) {
+
+            Rectangle2D oldBounds = new Rectangle2D(0, 0, getWidth(), oldHeight.doubleValue());
+            Rectangle2D newBounds = new Rectangle2D(0, 0, getWidth(), newHeight.doubleValue());
+            resizeSelectionToNewBounds(oldBounds, newBounds);
+        }
+
+        // RESIZE TO NODE
+
+        /**
+         * Resizes the current {@link SnapshotView#selectionProperty() selection} from the control's to the node's
+         * bounds
+         */
+        private void resizeSelectionFromControlToNode() {
+            if (getNode() == null) {
+                setSelection(null);
+            } else {
+                // transform the selection from the control's to the node's bounds
+                Rectangle2D controlBounds = new Rectangle2D(0, 0, getWidth(), getHeight());
+                Rectangle2D nodeBounds = Rectangles2D.fromBounds(getNode().getBoundsInParent());
+                resizeSelectionToNewBounds(controlBounds, nodeBounds);
+            }
+        }
+
+        /**
+         * Moves the {@link #resizeSelectionToNewNodeBoundsListener} from the specified old to the specified new node's
+         * {@link Node#boundsInParentProperty() boundsInParent} property and resizes the current
+         * {@link SnapshotView#selectionProperty() selection} from the old to the new node's bounds.
+         * <p>
+         * Designed to be used as a lambda method reference.
+         * 
+         * @param o
+         *            the {@link ObservableValue} which changed its value
+         * @param oldNode
+         *            the old node
+         * @param newNode
+         *            the new node
+         */
+        private void updateSelectionToNewNode(
+                @SuppressWarnings("unused") ObservableValue<? extends Node> o, Node oldNode, Node newNode) {
+
+            // move the bounds listener from the old to the new node
+            if (oldNode != null) {
+                oldNode.boundsInParentProperty().removeListener(resizeSelectionToNewNodeBoundsListener);
+            }
+            if (newNode != null) {
+                newNode.boundsInParentProperty().addListener(resizeSelectionToNewNodeBoundsListener);
+            }
+
+            // update selection
+            if (oldNode == null || newNode == null) {
+                // if one of the nodes is null, set no selection
+                setSelection(null);
+            } else {
+                // transform the current selection
+                resizeSelectionToNewNodeBounds(null, oldNode.getBoundsInParent(), newNode.getBoundsInParent());
+            }
+        }
+
+        /**
+         * Resizes the current {@link SnapshotView#selectionProperty() selection} from the specified old to the
+         * specified new bounds of the {@link SnapshotView#nodeProperty() node}.
+         * 
+         * @param o
+         *            the {@link ObservableValue} which changed its value
+         * @param oldBounds
+         *            the node's old bounds
+         * @param newBounds
+         *            the node's new bounds
+         */
+        private void resizeSelectionToNewNodeBounds(
+                @SuppressWarnings("unused") ObservableValue<? extends Bounds> o, Bounds oldBounds, Bounds newBounds) {
+
+            resizeSelectionToNewBounds(Rectangles2D.fromBounds(oldBounds), Rectangles2D.fromBounds(newBounds));
+        }
+
+        // GENERAL RESIZING
+
+        /**
+         * If this control {@link SnapshotView#hasSelection() has a selection} it is resized from the specified old to
+         * the specified new bounds.
+         * 
+         * @param oldBounds
+         *            the {@link SnapshotView#selectionProperty() selection}'s old bounds as a {@link Rectangle2D}
+         * @param newBounds
+         *            the {@link SnapshotView#selectionProperty() selection}'s new bounds as a {@link Rectangle2D}
+         */
+        private void resizeSelectionToNewBounds(Rectangle2D oldBounds, Rectangle2D newBounds) {
+            if (!hasSelection()) {
+                return;
+            }
+
+            Rectangle2D newSelection = transformSelectionToNewBounds(getSelection(), oldBounds, newBounds);
+            if (isSelectionValid(newSelection)) {
+                setSelection(newSelection);
+            } else {
+                setSelection(null);
+            }
+        }
+
+        /**
+         * Returns a new selection which is a transformation of the specified old selection. The transformation is such
+         * that the new selection's "relative position" in the specified new bounds is the same as the old selection's
+         * relative position in the specified old bounds.
+         * <p>
+         * Here, "relative position" is a representation of the selection where the coordinates of its upper left point
+         * and its width and height are expressed in a percentage of its bounds. Those percentages are the same for
+         * "old selection in old bounds" and "returned selection in new bounds"
+         * 
+         * @param oldSelection
+         *            the selection to be transformed as a {@link Rectangle2D}
+         * @param oldBounds
+         *            the {@code oldSelection}'s old bounds as a {@link Rectangle2D}
+         * @param newBounds
+         *            the {@code oldSelection}'s new bounds as a {@link Rectangle2D}
+         * @return s {@link Rectangle2D} which is the transformation of the old selection to the new bounds
+         */
+        private Rectangle2D transformSelectionToNewBounds(
+                Rectangle2D oldSelection, Rectangle2D oldBounds, Rectangle2D newBounds) {
+
+            Point2D newSelectionCenter = computeNewSelectionCenter(oldSelection, oldBounds, newBounds);
+
+            double widthRatio = newBounds.getWidth() / oldBounds.getWidth();
+            double heightRatio = newBounds.getHeight() / oldBounds.getHeight();
+
+            if (isSelectionRatioFixed()) {
+                double newArea = (oldSelection.getWidth() * widthRatio) * (oldSelection.getHeight() * heightRatio);
+                double ratio = getFixedSelectionRatio();
+                return Rectangles2D.forCenterAndAreaAndRatioWithinBounds(newSelectionCenter, newArea, ratio, newBounds);
+            } else {
+                double newWidth = oldSelection.getWidth() * widthRatio;
+                double newHeight = oldSelection.getHeight() * heightRatio;
+                return Rectangles2D.forCenterAndSize(newSelectionCenter, newWidth, newHeight);
+            }
+        }
+
+        /**
+         * Computes a point with the same relative position in the specified new bounds as the specified old selection's
+         * center point in the specified old bounds. (See
+         * {@link #transformSelectionToNewBounds(Rectangle2D, Rectangle2D, Rectangle2D) transformSelectionToNewBounds}
+         * for a definition of "relative position").
+         * 
+         * @param oldSelection
+         *            the selection whose center point is the base for the returned center point as a
+         *            {@link Rectangle2D}
+         * @param oldBounds
+         *            the bounds of the old selection as a {@link Rectangle2D}
+         * @param newBounds
+         *            the bounds for the new selection as a {@link Rectangle2D}
+         * @return a {@link Point2D} with the same relative position in the new bounds as the old selection's center
+         *         point in the old bounds
+         */
+        private Point2D computeNewSelectionCenter(Rectangle2D oldSelection, Rectangle2D oldBounds, Rectangle2D newBounds) {
+
+            Point2D oldSelectionCenter = Rectangles2D.getCenterPoint(oldSelection);
+            Point2D oldBoundsCenter = Rectangles2D.getCenterPoint(oldBounds);
+            Point2D oldSelectionCenterOffset = oldSelectionCenter.subtract(oldBoundsCenter);
+
+            double widthRatio = newBounds.getWidth() / oldBounds.getWidth();
+            double heightRatio = newBounds.getHeight() / oldBounds.getHeight();
+
+            Point2D newSelectionCenterOffset = new Point2D(
+                    oldSelectionCenterOffset.getX() * widthRatio, oldSelectionCenterOffset.getY() * heightRatio);
+            Point2D newBoundsCenter = Rectangles2D.getCenterPoint(newBounds);
+            Point2D newSelectionCenter = newBoundsCenter.add(newSelectionCenterOffset);
+
+            return newSelectionCenter;
+        }
+
+    }
+
+}
diff --git a/src/org/controlsfx/control/StatusBar.java b/src/org/controlsfx/control/StatusBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..40273de30471aad5476915bc0edf683aa208e7cb
--- /dev/null
+++ b/src/org/controlsfx/control/StatusBar.java
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import static impl.org.controlsfx.i18n.Localization.asKey;
+import static impl.org.controlsfx.i18n.Localization.localize;
+
+import impl.org.controlsfx.skin.StatusBarSkin;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.Node;
+import javafx.scene.control.ProgressBar;
+import javafx.scene.control.Skin;
+
+/**
+ * The StatusBar control is normally placed at the bottom of a window. It is
+ * used to display various types of application status information. This can be
+ * a text message, the progress of a task, or any other kind of status (e.g. red
+ * / green / yellow lights). By default the status bar contains a label for
+ * displaying plain text and a progress bar (see {@link ProgressBar}) for long
+ * running tasks. Additional controls / nodes can be placed on the left and
+ * right sides (see {@link #getLeftItems()} and {@link #getRightItems()}).
+ * 
+ * <h3>Screenshots</h3> 
+ * The picture below shows the default appearance of the StatusBar control: 
+ * <center><img src="statusbar.png" alt="Screenshot of StatusBar"></center> 
+ * 
+ * <br>
+ * The following picture shows the status bar reporting progress of a task:
+ * <center><img src="statusbar-progress.png" alt="Screenshot of StatusBar 
+ * reporting progress of a task"></center> 
+ * 
+ * <br>
+ * The last picture shows the status bar reporting progress, along with a couple 
+ * of extra items added to the left and right areas of the bar: 
+ * <center><img src="statusbar-items.png" alt="Screenshot of StatusBar
+ * reporting progress, along with a couple of extra items"></center>
+ * 
+ * <h3>Code Sample</h3>
+ * 
+ * <pre>
+ * StatusBar statusBar = new StatusBar();
+ * statusBar.getLeftItems().add(new Button(&quot;Info&quot;));
+ * statusBar.setProgress(.5);
+ * </pre>
+ */
+public class StatusBar extends ControlsFXControl {
+
+    /**
+     * Constructs a new status bar control.
+     */
+    public StatusBar() {
+        getStyleClass().add("status-bar"); //$NON-NLS-1$
+    }
+
+    @Override
+    protected Skin<?> createDefaultSkin() {
+        return new StatusBarSkin(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(StatusBar.class, "statusbar.css");
+    }
+    
+    private final StringProperty text = new SimpleStringProperty(this, "text", //$NON-NLS-1$
+            localize(asKey("statusbar.ok"))); //$NON-NLS-1$
+
+    /**
+     * The property used for storing the text message shown by the status bar.
+     * 
+     * @return the text message property
+     */
+    public final StringProperty textProperty() {
+        return text;
+    }
+
+    /**
+     * Sets the value of the {@link #textProperty()}.
+     * 
+     * @param text the text shown by the label control inside the status bar
+     */
+    public final void setText(String text) {
+        textProperty().set(text);
+    }
+
+    /**
+     * Returns the value of the {@link #textProperty()}. 
+     * 
+     * @return the text currently shown by the status bar
+     */
+    public final String getText() {
+        return textProperty().get();
+    }
+
+    private final ObjectProperty<Node> graphic = new SimpleObjectProperty<>(
+            this, "graphic"); //$NON-NLS-1$
+
+    /**
+     * The property used to store a graphic node that can be displayed by the 
+     * status label inside the status bar control.
+     * 
+     * @return the property used for storing a graphic node
+     */
+    public final ObjectProperty<Node> graphicProperty() {
+        return graphic;
+    }
+
+    /**
+     * Returns the value of the {@link #graphicProperty()}.
+     * 
+     * @return the graphic node shown by the label inside the status bar
+     */
+    public final Node getGraphic() {
+        return graphicProperty().get();
+    }
+
+    /**
+     * Sets the value of {@link #graphicProperty()}.
+     * 
+     * @param node the graphic node shown by the label inside the status bar
+     */
+    public final void setGraphic(Node node) {
+        graphicProperty().set(node);
+    }
+
+    private final ObservableList<Node> leftItems = FXCollections
+            .observableArrayList();
+
+    /**
+     * Returns the list of items / nodes that will be shown to the left of the status label.
+     * 
+     * @return the items on the left-hand side of the status bar
+     */
+    public final ObservableList<Node> getLeftItems() {
+        return leftItems;
+    }
+
+    private final ObservableList<Node> rightItems = FXCollections
+            .observableArrayList();
+
+    /**
+     * Returns the list of items / nodes that will be shown to the right of the status label.
+     * 
+     * @return the items on the left-hand side of the status bar
+     */
+    public final ObservableList<Node> getRightItems() {
+        return rightItems;
+    }
+
+    private final DoubleProperty progress = new SimpleDoubleProperty(this,
+            "progress"); //$NON-NLS-1$
+
+    /**
+     * The property used to store the progress, a value between 0 and 1. A negative
+     * value causes the progress bar to show an indeterminate state.
+     * 
+     * @return the property used to store the progress of a task
+     */
+    public final DoubleProperty progressProperty() {
+        return progress;
+    }
+
+    /**
+     * Sets the value of the {@link #progressProperty()}.
+     * 
+     * @param progress the new progress value
+     */
+    public final void setProgress(double progress) {
+        progressProperty().set(progress);
+    }
+
+    /**
+     * Returns the value of {@link #progressProperty()}.
+     * 
+     * @return the current progress value
+     */
+    public final double getProgress() {
+        return progressProperty().get();
+    }
+}
diff --git a/src/org/controlsfx/control/TaskProgressView.java b/src/org/controlsfx/control/TaskProgressView.java
new file mode 100644
index 0000000000000000000000000000000000000000..839d4ceb360e5b2f5d0789e9d2dd3bff4ad34e52
--- /dev/null
+++ b/src/org/controlsfx/control/TaskProgressView.java
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.TaskProgressViewSkin;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.concurrent.Task;
+import javafx.concurrent.WorkerStateEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.Skin;
+import javafx.util.Callback;
+
+/**
+ * The task progress view is used to visualize the progress of long running
+ * tasks. These tasks are created via the {@link Task} class. This view
+ * manages a list of such tasks and displays each one of them with their
+ * name, progress, and update messages.<p>
+ * An optional graphic factory can be set to place a graphic in each row.
+ * This allows the user to more easily distinguish between different types
+ * of tasks.
+ *
+ * <h3>Screenshots</h3>
+ * The picture below shows the default appearance of the task progress view
+ * control:
+ * <center><img src="task-monitor.png" alt="Screenshot of TaskProgressView"></center>
+ *
+ * <h3>Code Sample</h3>
+ * <pre>
+ * TaskProgressView&lt;MyTask&gt; view = new TaskProgressView&lt;&gt;();
+ * view.setGraphicFactory(task -&gt; return new ImageView("db-access.png"));
+ * view.getTasks().add(new MyTask());
+ * </pre>
+ */
+public class TaskProgressView<T extends Task<?>> extends ControlsFXControl {
+
+    /**
+     * Constructs a new task progress view.
+     */
+    public TaskProgressView() {
+        getStyleClass().add("task-progress-view");
+
+        EventHandler<WorkerStateEvent> taskHandler = evt -> {
+            if (evt.getEventType().equals(
+                    WorkerStateEvent.WORKER_STATE_SUCCEEDED)
+                    || evt.getEventType().equals(
+                            WorkerStateEvent.WORKER_STATE_CANCELLED)
+                    || evt.getEventType().equals(
+                            WorkerStateEvent.WORKER_STATE_FAILED)) {
+                getTasks().remove(evt.getSource());
+            }
+        };
+
+        getTasks().addListener(new ListChangeListener<Task<?>>() {
+            @Override
+            public void onChanged(Change<? extends Task<?>> c) {
+                while (c.next()) {
+                    if (c.wasAdded()) {
+                        for (Task<?> task : c.getAddedSubList()) {
+                            task.addEventHandler(WorkerStateEvent.ANY,
+                                    taskHandler);
+                        }
+                    } else if (c.wasRemoved()) {
+                        for (Task<?> task : c.getRemoved()) {
+                            task.removeEventHandler(WorkerStateEvent.ANY,
+                                    taskHandler);
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getUserAgentStylesheet() {
+        return getUserAgentStylesheet(TaskProgressView.class, "taskprogressview.css");
+    }
+    
+    @Override
+    protected Skin<?> createDefaultSkin() {
+        return new TaskProgressViewSkin<>(this);
+    }
+
+    private final ObservableList<T> tasks = FXCollections
+            .observableArrayList();
+
+    /**
+     * Returns the list of tasks currently monitored by this view.
+     *
+     * @return the monitored tasks
+     */
+    public final ObservableList<T> getTasks() {
+        return tasks;
+    }
+
+    private ObjectProperty<Callback<T, Node>> graphicFactory;
+
+    /**
+     * Returns the property used to store an optional callback for creating
+     * custom graphics for each task.
+     *
+     * @return the graphic factory property
+     */
+    public final ObjectProperty<Callback<T, Node>> graphicFactoryProperty() {
+        if (graphicFactory == null) {
+            graphicFactory = new SimpleObjectProperty<Callback<T, Node>>(
+                    this, "graphicFactory");
+        }
+
+        return graphicFactory;
+    }
+
+    /**
+     * Returns the value of {@link #graphicFactoryProperty()}.
+     *
+     * @return the optional graphic factory
+     */
+    public final Callback<T, Node> getGraphicFactory() {
+        return graphicFactory == null ? null : graphicFactory.get();
+    }
+
+    /**
+     * Sets the value of {@link #graphicFactoryProperty()}.
+     *
+     * @param factory an optional graphic factory
+     */
+    public final void setGraphicFactory(Callback<T, Node> factory) {
+        graphicFactoryProperty().set(factory);
+    }
+}
diff --git a/src/org/controlsfx/control/ToggleSwitch.java b/src/org/controlsfx/control/ToggleSwitch.java
new file mode 100644
index 0000000000000000000000000000000000000000..d380eaddbfbb04f8799586a44850c64de0c2af9c
--- /dev/null
+++ b/src/org/controlsfx/control/ToggleSwitch.java
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.controlsfx.control;
+
+import impl.org.controlsfx.skin.ToggleSwitchSkin;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.BooleanPropertyBase;
+import javafx.css.PseudoClass;
+import javafx.event.ActionEvent;
+import javafx.scene.control.Labeled;
+import javafx.scene.control.Skin;
+
+/**
+ * Much like a Toggle Button this control allows the user to toggle between one of two states. It has been popularized
+ * in touch based devices where its usage is particularly useful because unlike a checkbox the finger touch of a user
+ * doesn't obscure the control.
+ *
+ * <p> Shown below is a screenshot of the ToggleSwitch control in its on and off state:
+ * <br>
+ * <center>
+ * <img src="ToggleSwitch.png" alt="Screenshot of ToggleSwitch">
+ * </center>
+ */
+public class ToggleSwitch extends Labeled
+{
+
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Creates a toggle switch with empty string for its label.
+     */
+    public ToggleSwitch() {
+        initialize();
+    }
+
+    /**
+     * Creates a toggle switch with the specified label.
+     *
+     * @param text The label string of the control.
+     */
+    public ToggleSwitch(String text) {
+        super(text);
+        initialize();
+    }
+
+    private void initialize() {
+        getStyleClass().setAll(DEFAULT_STYLE_CLASS);
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Properties                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Indicates whether this ToggleSwitch is selected.
+     */
+    private BooleanProperty selected;
+
+    /**
+     * Sets the selected value of this Toggle Switch
+     */
+    public final void setSelected(boolean value) {
+        selectedProperty().set(value);
+    }
+
+    /**
+     * Returns whether this Toggle Switch is selected
+     */
+    public final boolean isSelected() {
+        return selected == null ? false : selected.get();
+    }
+
+    /**
+     * Returns the selected property
+     */
+    public final BooleanProperty selectedProperty() {
+        if (selected == null) {
+            selected = new BooleanPropertyBase() {
+                @Override protected void invalidated() {
+                    final Boolean v = get();
+                    pseudoClassStateChanged(PSEUDO_CLASS_SELECTED, v);
+//                    accSendNotification(Attribute.SELECTED);
+                }
+
+                @Override
+                public Object getBean() {
+                    return ToggleSwitch.this;
+                }
+
+                @Override
+                public String getName() {
+                    return "selected";
+                }
+            };
+        }
+        return selected;
+    }
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Methods                                                                 *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Toggles the state of the {@code ToggleSwitch}. The {@code ToggleSwitch} will cycle through
+     * the selected and unselected states.
+     */
+    public void fire() {
+        if (!isDisabled()) {
+            setSelected(!isSelected());
+            fireEvent(new ActionEvent());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new ToggleSwitchSkin(this);
+    }
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Stylesheet Handling                                                     *
+     *                                                                         *
+     **************************************************************************/
+
+    private static final String DEFAULT_STYLE_CLASS = "toggle-switch";
+
+    private static final PseudoClass PSEUDO_CLASS_SELECTED =
+            PseudoClass.getPseudoClass("selected");
+
+    /** {@inheritDoc} */
+    @Override
+    public String getUserAgentStylesheet() {
+        return ToggleSwitch.class.getResource("toggleswitch.css").toExternalForm();
+    }
+
+}
diff --git a/src/org/controlsfx/control/action/Action.java b/src/org/controlsfx/control/action/Action.java
new file mode 100644
index 0000000000000000000000000000000000000000..04d84396097f0056afa9b270e0d557ad69f7612e
--- /dev/null
+++ b/src/org/controlsfx/control/action/Action.java
@@ -0,0 +1,430 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.action;
+
+import impl.org.controlsfx.i18n.Localization;
+import impl.org.controlsfx.i18n.SimpleLocalizedStringProperty;
+
+import java.util.function.Consumer;
+
+import javafx.beans.NamedArg;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.collections.ObservableMap;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.input.KeyCombination;
+
+/**
+ * A base class for Action API. 
+ * 
+ * <h3>What is an Action?</h3>
+ * An action in JavaFX can be used to separate functionality and state from a 
+ * control. For example, if you have two or more controls that perform the same 
+ * function (e.g. one in a {@link Menu} and another on a toolbar), consider 
+ * using an Action object to implement the function. An Action object provides 
+ * centralized handling of the state of action-event-firing components such as 
+ * buttons, menu items, etc. The state that an action can handle includes text, 
+ * graphic, long text (i.e. tooltip text), and disabled.
+ */
+public class Action implements EventHandler<ActionEvent> {
+    
+    /**************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+    private boolean locked = false;
+    
+    private Consumer<ActionEvent> eventHandler;
+    
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    public Action(@NamedArg("text") String text) {
+        this(text, null);
+    }
+    
+    public Action(Consumer<ActionEvent> eventHandler) {
+        this("", eventHandler); //$NON-NLS-1$
+    }
+   
+    /**
+     * Creates a new AbstractAction instance with the given String set as the 
+     * {@link #textProperty() text} value, as well as the {@code Consumer<ActionEvent>}
+     * set to be called when the action event is fired.
+     *  
+     * @param text The string to display in the text property of controls such
+     *      as {@link Button#textProperty() Button}.
+     * @param eventHandler This will be called when the ActionEvent is fired.
+     */
+    public Action(@NamedArg("text") String text, Consumer<ActionEvent> eventHandler) {
+        setText(text);
+        setEventHandler(eventHandler);
+        getStyleClass().add( "action" ); // this class will be added to all bound controls
+    }
+    
+    protected void lock() {
+    	locked = true;
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+    
+    // --- style
+    /**
+     * A string representation of the CSS style associated with this
+     * Action instance and passed to related UI controls. 
+     * This is analogous to the "style" attribute of an
+     * HTML element. Note that, like the HTML style attribute, this
+     * variable contains style properties and values and not the
+     * selector portion of a style rule.
+     * <p>
+     * Parsing this style might not be supported on some limited
+     * platforms. It is recommended to use a standalone CSS file instead.
+     */
+    private StringProperty style;
+    public final void setStyle(String value) { styleProperty().set(value); }
+    public final String getStyle() { return style == null ? "" : style.get(); } //$NON-NLS-1$
+    public final StringProperty styleProperty() {
+        if (style == null) {
+            style = new SimpleStringProperty(this, "style") { //$NON-NLS-1$
+            	@Override
+            	public void set(String style) {
+            		if (locked) throw new UnsupportedOperationException("The action is immutable, property change support is disabled."); //$NON-NLS-1$
+            		super.set(style);
+            	}
+            };
+        }
+        return style;
+    }
+
+
+    // --- Style class
+    private final ObservableList<String> styleClass = FXCollections.observableArrayList();
+    /**
+     * A list of String identifiers which can be used to logically group
+     * Nodes, specifically for an external style engine. This variable is
+     * analogous to the "class" attribute on an HTML element and, as such,
+     * each element of the list is a style class to which this Node belongs.
+     *
+     * @see <a href="http://www.w3.org/TR/css3-selectors/#class-html">CSS3 class selectors</a>
+     */
+    public ObservableList<String> getStyleClass() {
+        return styleClass;
+    }    
+    
+    
+    // --- selected 
+    private final BooleanProperty selectedProperty = new SimpleBooleanProperty(this, "selected") { //$NON-NLS-1$
+    	@Override public void set(boolean selected) {
+    		if (locked) throw new UnsupportedOperationException("The action is immutable, property change support is disabled."); //$NON-NLS-1$
+    		super.set(selected);
+    	}
+    };
+    
+    /**
+     * Represents action's selected state. 
+     * Usually bound to selected state of components such as Toggle Buttons, CheckBOxes  etc
+     *
+     * @return An observable {@link BooleanProperty} that represents the current
+     *      selected state, and which can be observed for changes.
+     */
+    public final BooleanProperty selectedProperty() {
+    	return selectedProperty;
+    }
+    
+    /**
+     * Selected state of the Action.
+     * @return The selected state of this action.
+     */
+    public final boolean isSelected() {
+    	return selectedProperty.get();
+    }
+    
+    /**
+     * Sets selected state of the Action
+     * @param selected
+     */
+    public final void setSelected( boolean selected ) {
+    	selectedProperty.set(selected);
+    }
+    
+    
+    // --- text
+    private final StringProperty textProperty = new SimpleLocalizedStringProperty(this, "text"){ //$NON-NLS-1$
+    	@Override public void set(String value) {
+    		if ( locked ) throw new RuntimeException("The action is immutable, property change support is disabled."); //$NON-NLS-1$
+    		super.set(value);
+    	}
+    };
+    
+    /**
+     * The text to show to the user.
+     * 
+     * @return An observable {@link StringProperty} that represents the current
+     *      text for this property, and which can be observed for changes.
+     */
+    public final StringProperty textProperty() {
+        return textProperty;
+    }
+    
+    /**
+     * 
+     * @return the text of the Action.
+     */
+    public final String getText() {
+        return textProperty.get();
+    }
+
+    /**
+     * Sets the text of the Action.
+     * @param value 
+     */
+    public final void setText(String value) {
+        textProperty.set(value);
+    }
+    
+    
+    // --- disabled
+    private final BooleanProperty disabledProperty = new SimpleBooleanProperty(this, "disabled"){ //$NON-NLS-1$
+        @Override public void set(boolean value) {
+    		if ( locked ) throw new RuntimeException("The action is immutable, property change support is disabled."); //$NON-NLS-1$
+    		super.set(value);
+    	}
+    };
+    
+    /**
+     * This represents whether the action should be available to the end user,
+     * or whether it should appeared 'grayed out'.
+     * 
+     * @return An observable {@link BooleanProperty} that represents the current
+     *      disabled state for this property, and which can be observed for 
+     *      changes.
+     */
+    public final BooleanProperty disabledProperty() {
+        return disabledProperty;
+    }
+    
+    /**
+     * 
+     * @return whether the action is available to the end user,
+     * or whether it should appeared 'grayed out'.
+     */
+    public final boolean isDisabled() {
+        return disabledProperty.get();
+    }
+    
+    /**
+     * Sets whether the action should be available to the end user,
+     * or whether it should appeared 'grayed out'.
+     * @param value 
+     */
+    public final void setDisabled(boolean value) {
+        disabledProperty.set(value);
+    }
+
+    
+    // --- longText
+    private final StringProperty longTextProperty = new SimpleLocalizedStringProperty(this, "longText"){ //$NON-NLS-1$
+        @Override public void set(String value) {
+    		if ( locked ) throw new RuntimeException("The action is immutable, property change support is disabled."); //$NON-NLS-1$
+    		super.set(value);
+
+    	}
+    };
+    
+    /**
+     * The longer form of the text to show to the user (e.g. on a 
+     * {@link Button}, it is usually a tooltip that should be shown to the user 
+     * if their mouse hovers over this action).
+     * 
+     * @return An observable {@link StringProperty} that represents the current
+     *      long text for this property, and which can be observed for changes.
+     */
+    public final StringProperty longTextProperty() {
+        return longTextProperty;
+    }
+    
+    /**
+     * @see #longTextProperty() 
+     * @return The longer form of the text to show to the user
+     */
+    public final String getLongText() {
+        return Localization.localize(longTextProperty.get());
+    }
+    
+    /**
+     * Sets the longer form of the text to show to the user
+     * @param value 
+     * @see #longTextProperty() 
+     */
+    public final void setLongText(String value) {
+        longTextProperty.set(value);
+    }
+    
+    
+    // --- graphic
+    private final ObjectProperty<Node> graphicProperty = new SimpleObjectProperty<Node>(this, "graphic"){ //$NON-NLS-1$
+        @Override public void set(Node value) {
+    		if ( locked ) throw new RuntimeException("The action is immutable, property change support is disabled."); //$NON-NLS-1$
+    		super.set(value);
+
+    	}
+    };
+    
+    /**
+     * The graphic that should be shown to the user in relation to this action.
+     * 
+     * @return An observable {@link ObjectProperty} that represents the current
+     *      graphic for this property, and which can be observed for changes.
+     */
+    public final ObjectProperty<Node> graphicProperty() {
+        return graphicProperty;
+    }
+    
+    /**
+     * 
+     * @return The graphic that should be shown to the user in relation to this action.
+     */
+    public final Node getGraphic() {
+        return graphicProperty.get();
+    }
+    
+    /**
+     * Sets the graphic that should be shown to the user in relation to this action.
+     * @param value 
+     */
+    public final void setGraphic(Node value) {
+        graphicProperty.set(value);
+    }
+    
+    
+    // --- accelerator
+    private final ObjectProperty<KeyCombination> acceleratorProperty = new SimpleObjectProperty<KeyCombination>(this, "accelerator"){ //$NON-NLS-1$
+        @Override public void set(KeyCombination value) {
+    		if ( locked ) throw new RuntimeException("The action is immutable, property change support is disabled."); //$NON-NLS-1$
+    		super.set(value);
+
+    	}
+    };
+    
+    /**
+     * The accelerator {@link KeyCombination} that should be used for this action,
+     * if it is used in an applicable UI control (most notably {@link MenuItem}).
+     * 
+     * @return An observable {@link ObjectProperty} that represents the current
+     *      accelerator for this property, and which can be observed for changes.
+     */
+    public final ObjectProperty<KeyCombination> acceleratorProperty() {
+        return acceleratorProperty;
+    }
+    
+    /**
+     * 
+     * @return The accelerator {@link KeyCombination} that should be used for this action,
+     * if it is used in an applicable UI control
+     */
+    public final KeyCombination getAccelerator() {
+        return acceleratorProperty.get();
+    }
+    
+    /**
+     * Sets the accelerator {@link KeyCombination} that should be used for this action,
+     * if it is used in an applicable UI control
+     * @param value 
+     */
+    public final void setAccelerator(KeyCombination value) {
+        acceleratorProperty.set(value);
+    }
+    
+    
+    // --- properties
+    private ObservableMap<Object, Object> props;
+    
+    /**
+     * Returns an observable map of properties on this Action for use primarily
+     * by application developers.
+     *
+     * @return An observable map of properties on this Action for use primarily
+     * by application developers
+     */
+    public final synchronized ObservableMap<Object, Object> getProperties() {
+    	if ( props == null ) props = FXCollections.observableHashMap();
+    	return props;
+    }
+    
+    protected Consumer<ActionEvent> getEventHandler() {
+		return eventHandler;
+	}
+    
+    protected void setEventHandler(Consumer<ActionEvent> eventHandler) {
+		this.eventHandler = eventHandler;
+	}
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    /** 
+     * Defers to the {@code Consumer<ActionEvent>} passed in to the Action constructor.
+     */
+    @Override public final void handle(ActionEvent event) {
+        if (eventHandler != null && !isDisabled()) {
+            eventHandler.accept(event);
+        }
+    }
+    
+//    public void bind(ButtonBase button) {
+//        ActionUtils.configureButton(this, button);
+//    }
+//    
+//    public void bind(MenuItem menuItem) {
+//        ActionUtils.configureMenuItem(this, menuItem);
+//    }
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/action/ActionCheck.java b/src/org/controlsfx/control/action/ActionCheck.java
new file mode 100644
index 0000000000000000000000000000000000000000..b59ed061125546331353db1601daf281fab4927a
--- /dev/null
+++ b/src/org/controlsfx/control/action/ActionCheck.java
@@ -0,0 +1,21 @@
+package org.controlsfx.control.action;
+
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckMenuItem;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.ToggleButton;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks the {@link Action} or a method annotated with {@link ActionProxy} to let action engine know
+ * that {@link ToggleButton} or {@link CheckMenuItem} has to be bound to the action
+ * instead of standard {@link Button} and {@link MenuItem}
+ */
+@Target( { ElementType.TYPE, ElementType.METHOD } )
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ActionCheck {
+}
diff --git a/src/org/controlsfx/control/action/ActionGroup.java b/src/org/controlsfx/control/action/ActionGroup.java
new file mode 100644
index 0000000000000000000000000000000000000000..06ab1f00c33aae68bb500fc45e7eb12ee24f2f8d
--- /dev/null
+++ b/src/org/controlsfx/control/action/ActionGroup.java
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.action;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.Node;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuBar;
+import javafx.scene.control.ToolBar;
+
+/**
+ * An ActionGroup (unsurprisingly) groups together zero or more {@link Action} 
+ * instances, allowing for more complex controls like {@link ToolBar}, 
+ * {@link MenuBar} and {@link ContextMenu} to be automatically generated from
+ * the collection of actions inside the ActionGroup. For your convenience,
+ * there are a number of utility methods that do precisely this in the 
+ * {@link ActionUtils} class.
+ * 
+ * <h3>Code Examples</h3>
+ * <p>Consider the following code example (note that DummyAction is a fake class
+ * that extends from (and implements) {@link Action}):
+ * 
+ * <pre>
+ * {@code
+ * // Firstly, create a list of Actions
+ * Collection<? extends Action> actions = Arrays.asList(
+ *     new ActionGroup("Group 1",  new DummyAction("Action 1.1"), 
+ *                                 new DummyAction("Action 2.1") ),
+ *     new ActionGroup("Group 2",  new DummyAction("Action 2.1"), 
+ *                                 new ActionGroup("Action 2.2", new DummyAction("Action 2.2.1"), 
+ *                                                               new DummyAction("Action 2.2.2")),
+ *                                 new DummyAction("Action 2.3") ),
+ *     new ActionGroup("Group 3",  new DummyAction("Action 3.1"), 
+ *                                 new DummyAction("Action 3.2") )
+ *   );
+ *   
+ *   // Use the ActionUtils class to create UI controls from these actions, e.g:
+ *   MenuBar menuBar = ActionUtils.createMenuBar(actions);
+ *   
+ *   ToolBar toolBar = ActionUtils.createToolBar(actions);
+ *   
+ *   Label context = new Label("Right-click to see the context menu");
+ *   context.setContextMenu(ActionUtils.createContextMenu(actions));  
+ * }</pre>
+ * 
+ * <p>The end result of running the code above is shown in the screenshots below
+ * (hopefully it goes without saying that within the 'Group 1', 'Group 2' and 
+ * 'Group 3' options are the 'Action 1.1', etc actions that have been specified
+ * in the code above):
+ *
+ * <table border="0" summary="ActionGroup Screenshots">
+ *   <tr>
+ *     <td width="75" valign="center"><strong>MenuBar:</strong></td>
+ *     <td><img src="actionGroup-menubar.png" alt="Screenshot of ActionGroup in a MenuBar"></td>
+ *   </tr>
+ *   <tr>
+ *     <td width="75" valign="center"><strong>ToolBar:</strong></td>
+ *     <td><img src="actionGroup-toolbar.png" alt="Screenshot of ActionGroup in a ToolBar"></td>
+ *   </tr>
+ *   <tr>
+ *   <td width="75" valign="top"><strong>ContextMenu:</strong></td>
+ *     <td><img src="actionGroup-contextmenu.png" alt="Screenshot of ActionGroup in a ContextMenu"></td>
+ *   </tr>
+ * </table>
+ * 
+ * @see Action
+ * @see ActionUtils
+ */
+public class ActionGroup extends Action {
+    
+    /**
+     * Creates an ActionGroup with the given text as the name of the {@link Action}, 
+     * and zero or more Actions as members of this ActionGroup. Note that it is
+     * legitimate to pass in zero Actions to this constructor, and to later 
+     * set the actions directly into the {@link #getActions() actions} list.
+     * 
+     * @param text The {@link Action#textProperty() text} of this {@link Action}.
+     * @param actions Zero or more actions to insert into this ActionGroup.
+     */
+    public ActionGroup(String text, Action... actions) {
+    	 this(text, Arrays.asList(actions));
+    }
+    
+    /**
+     * Creates an ActionGroup with the given text as the name of the {@link Action}, 
+     * and collection of Actions as members of this ActionGroup. 
+     * 
+     * @param text The {@link Action#textProperty() text} of this {@link Action}.
+     * @param actions Collection of actions to insert into this ActionGroup.
+     */
+    public ActionGroup(String text, Collection<Action> actions) {
+        super(text);
+        getActions().addAll(actions);
+    }
+    
+    /**
+     * Creates an ActionGroup with the given text as the name of the {@link Action}, 
+     * and zero or more Actions as members of this ActionGroup. Note that it is
+     * legitimate to pass in zero Actions to this constructor, and to later 
+     * set the actions directly into the {@link #getActions() actions} list.
+     * 
+     * @param text The {@link Action#textProperty() text} of this {@link Action}.
+     * @param icon The {@link Action#graphicProperty() image} of this {@link Action}.
+     * @param actions Zero or more actions to insert into this ActionGroup.
+     */
+    public ActionGroup(String text, Node icon, Action... actions) {
+    	 this( text, icon, Arrays.asList(actions));
+    }
+    
+    /**
+     * Creates an ActionGroup with the given text as the name of the {@link Action},
+     * and collection of Actions as members of this ActionGroup. .
+     * 
+     * @param text The {@link Action#textProperty() text} of this {@link Action}.
+     * @param icon The {@link Action#graphicProperty() image} of this {@link Action}.
+     * @param actions Collection of actions to insert into this ActionGroup.
+     */
+    public ActionGroup(String text, Node icon, Collection<Action> actions) {
+        super(text);
+        setGraphic(icon);
+        getActions().addAll(actions);
+    }
+
+    // --- actions
+    private final ObservableList<Action> actions = FXCollections.<Action> observableArrayList();
+
+    /**
+     * The list of {@link Action} instances that exist within this ActionGroup.
+     * This list may be modified, as shown in the class documentation.
+     */
+    public final ObservableList<Action> getActions() {
+        return actions;
+    }
+    
+    @Override public String toString() {
+        return getText();
+    }
+    
+}
diff --git a/src/org/controlsfx/control/action/ActionMap.java b/src/org/controlsfx/control/action/ActionMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8e838009cf6d0cda6efe414411e49d45bc373a9
--- /dev/null
+++ b/src/org/controlsfx/control/action/ActionMap.java
@@ -0,0 +1,224 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.action;
+
+import javafx.event.ActionEvent;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * Action Map provides an ability to create an action map of any object.
+ * Attempts to convert methods annotated with {@link ActionProxy} to {@link Action}. 
+ * 
+ * <h3>Code Example</h3>
+ * Here's a very simple example of how to use ActionMap to register a class (in
+ * this class it is the application class itself), and to then retrieve actions
+ * out of the ActionMap (via the static {@link ActionMap#action(String)} method:
+ * <br>
+ * 
+ * <pre>
+ * public class ActionMapDemo extends Application {
+ *     public ActionMapDemo() {
+ *         ActionMap.register(this);
+ *         Action action11 = ActionMap.action("action11");
+ *         Button actionButton = ActionUtils.createButton(action11);
+ *     }
+ *  
+ *     &#64;ActionProxy(text="Action 1.1", graphic="start.png", accelerator="ctrl+shift+T")
+ *     private void action11() {
+ *         System.out.println( "Action 1.1 is executed");
+ *     }
+ * }
+ * </pre>
+ * 
+ * If you require more control over the creation of the Action objects, you can either set the
+ * global ActionFactory by calling ActionMap.setActionFactory() and/or you can use the factory 
+ * property on individual &#64;ActionProxy declarations to set the factory on a case-by-case basis.
+ * 
+ * @see ActionProxy
+ * @see Action
+ */
+public class ActionMap {
+
+    private static AnnotatedActionFactory actionFactory = new DefaultActionFactory();
+    
+    private static final Map<String, AnnotatedAction> actions = new HashMap<>();
+    
+
+    private ActionMap() {
+        // no-op
+    }
+
+
+    /**
+     * Returns the action factory used by ActionMap to construct AnnotatedAction instances. By default, this
+     * is an instance of {@link DefaultActionFactory}.
+     */
+    public static AnnotatedActionFactory getActionFactory() {
+        return actionFactory;
+    }
+
+    /**
+     * Sets the action factory used by ActionMap to construct AnnotatedAction instances. This factory can be overridden on
+     * a case-by-case basis by specifying a factory class in {@link ActionProxy#factory()}
+     */
+    public static void setActionFactory( AnnotatedActionFactory factory ) {
+        Objects.requireNonNull( factory );
+        actionFactory = factory;
+    }
+    
+    
+    
+    
+    /**
+     * Attempts to convert target's methods annotated with {@link ActionProxy} to {@link Action}s.
+     * Three types of methods are currently converted: parameter-less methods, 
+     * methods with one parameter of type {@link ActionEvent}, and methods with two parameters
+     * ({@link ActionEvent}, {@link Action}).
+     * 
+     * Note that this method supports safe re-registration of a given instance or of another instance of the
+     * same class that has already been registered. If another instance of the same class is registered, then
+     * those actions will now be associated with the new instance. The first instance is implicitly unregistered.
+     * 
+     * Actions are registered with their id or method name if id is not defined.
+     * 
+     * @param target object to work on
+     * @throws IllegalStateException if a method with unsupported parameters is annotated with {@link ActionProxy}.
+     */
+    public static void register(Object target) {
+
+        for (Method method : target.getClass().getDeclaredMethods()) {
+            // Only process methods that have the ActionProxy annotation
+            Annotation[] annotations = method.getAnnotationsByType(ActionProxy.class);
+            if (annotations.length == 0) {
+                continue;
+            }
+            
+            // Only process methods that have
+            // a) no parameters OR 
+            // b) one parameter of type ActionEvent OR
+            // c) two parameters (ActionEvent, Action)
+            int paramCount = method.getParameterCount();
+            Class[] paramTypes = method.getParameterTypes();
+            
+            if (paramCount > 2) {
+                throw new IllegalArgumentException( String.format( "Method %s has too many parameters", method.getName() ) );
+            }
+            
+            if (paramCount == 1 && !ActionEvent.class.isAssignableFrom( paramTypes[0] )) {
+                throw new IllegalArgumentException( String.format( "Method %s -- single parameter must be of type ActionEvent", method.getName() ) );
+            }
+            
+            if (paramCount == 2 && (!ActionEvent.class.isAssignableFrom( paramTypes[0] ) || 
+                                    !Action.class.isAssignableFrom( paramTypes[1] ))) {
+                throw new IllegalArgumentException( String.format( "Method %s -- parameters must be of types (ActionEvent, Action)", method.getName() ) );
+            }
+            
+            ActionProxy annotation = (ActionProxy) annotations[0];
+
+            AnnotatedActionFactory factory = determineActionFactory( annotation );
+            AnnotatedAction action = factory.createAction( annotation, method, target );
+
+            String id = annotation.id().isEmpty() ? method.getName() : annotation.id();
+            actions.put( id, action );
+        }
+    }
+    
+    
+    
+    
+    private static AnnotatedActionFactory determineActionFactory( ActionProxy annotation ) {
+        // Default to using the global action factory
+        AnnotatedActionFactory factory = actionFactory;
+        
+        // If an action-factory has been specified on this specific ActionProxy, then
+        // instantiate it and use it instead.
+        String factoryClassName = annotation.factory();
+        if (!factoryClassName.isEmpty()) {
+            try {
+                Class factoryClass = Class.forName( factoryClassName );
+                factory = (AnnotatedActionFactory) factoryClass.newInstance();
+
+            } catch (ClassNotFoundException ex) {
+                throw new IllegalArgumentException( String.format( "Action proxy refers to non-existant factory class %s", factoryClassName ), ex );
+
+            } catch (InstantiationException | IllegalAccessException ex) {
+                throw new IllegalStateException( String.format( "Unable to instantiate action factory class %s", factoryClassName ), ex );
+            }
+        }
+        
+        return factory;
+    }
+    
+    
+    /**
+     * Removes all the actions associated with target object from the action map.
+     * @param target object to work on
+     */
+    public static void unregister(Object target) {
+        if ( target != null ) {
+            Iterator<Map.Entry<String, AnnotatedAction>> entryIter = actions.entrySet().iterator();
+            while (entryIter.hasNext()) {
+                Map.Entry<String, AnnotatedAction> entry = entryIter.next();
+                
+                Object actionTarget = entry.getValue().getTarget();
+                
+                if (actionTarget == null || actionTarget == target) {
+                    entryIter.remove();
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns action by its id.
+     * @param id action id
+     * @return action or null if id was not found
+     */
+    public static Action action(String id) {
+        return actions.get(id);
+    }
+
+    /**
+     * Returns collection of actions by ids. Useful to create {@link ActionGroup}s.
+     * Ids starting with "---" are converted to {@link ActionUtils#ACTION_SEPARATOR}.
+     * Incorrect ids are ignored. 
+     * @param ids action ids
+     * @return collection of actions
+     */
+    public static Collection<Action> actions(String... ids) {
+        List<Action> result = new ArrayList<>();
+        for( String id: ids ) {
+            if ( id.startsWith("---")) result.add(ActionUtils.ACTION_SEPARATOR); //$NON-NLS-1$
+            Action action = action(id);
+            if ( action != null ) result.add(action);
+        }
+        return result;
+    }
+}
diff --git a/src/org/controlsfx/control/action/ActionProxy.java b/src/org/controlsfx/control/action/ActionProxy.java
new file mode 100644
index 0000000000000000000000000000000000000000..30f9064f36740a0f94240055b5389131c0f9acdc
--- /dev/null
+++ b/src/org/controlsfx/control/action/ActionProxy.java
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.action;
+
+import javafx.event.ActionEvent;
+import org.controlsfx.glyphfont.Glyph;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation to allow conversion of class methods to {@link Action} instances.
+ * 
+ * <p>The following steps are required to use {@link ActionProxy} annotations:
+ * 
+ * <ol>
+ * <li>Annotate your methods with the {@link ActionProxy} annotation. For example:
+ * <pre>{@code @ActionProxy(text="Action 1.1", graphic=imagePath, accelerator="ctrl+shift+T")
+ * private void action11() {
+ *     System.out.println("Action 1.1 is executed");
+ * }}</pre>
+ * 
+ * <p>The ActionProxy annotation is designed to work with three types of methods: 
+ * <ol>
+ *     <li>Methods with no parameters, 
+ *     <li>Methods with one parameter of type {@link ActionEvent}.
+ *     <li>Methods that take both an {@link ActionEvent} and an {@link Action}.
+ * </ol> 
+ * 
+ * <p>The ActionProxy annotation {@link #graphic()} property supports different node types:
+ * <ol>
+ *     <li>Images,
+ *     <li>Glyph fonts.
+ * </ol>
+ * 
+ * <p>The ability for ActionProxy to support glyph fonts is part of the ControlsFX
+ * {@link Glyph} API. For more information on how to specify
+ * images and glyph fonts, refer to the {@link ActionProxy#graphic()} method.
+ * <br><br></li>
+ * 
+ * <li>Register your class in the global {@link ActionMap}, preferably in the 
+ * class constructor:  
+ * <pre>{@code ActionMap.register(this); }</pre> 
+ * 
+ * Immediately after that actions will be created according to the provided 
+ * annotations and are accessible from {@link ActionMap}, which provides several 
+ * convenience methods to access actions by id. Refer to the {@link ActionMap}
+ * class for more details on how to use it.</li>
+ *
+ * <p>{@link ActionCheck} annotation is supported on the same method where @ActionProxy is applied}</p>
+ * </ol>
+ * 
+ * @see Action
+ * @see ActionMap
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ActionProxy {
+    
+    /**
+     * By default the method name that this annotation is applied to, but if not
+     * null then this ID is what you use when requesting the {@link Action} out
+     * of the {@link ActionMap} when using the {@link ActionMap#action(String)}
+     * method.
+     */
+	String id() default "";
+	
+	/**
+	 * The text that should be set in {@link Action#textProperty()}.
+	 */
+    String text();
+    
+    /**
+     * The graphic that should be set in {@link Action#graphicProperty()}.
+     * 
+     * <p>The graphic can be either image (local path or url) or font glyph. 
+     * 
+     * <p>Because a graphic can come from multiple sources, a simple protocol 
+     * prefix is used to designate the type. Currently supported prefixes are 
+     * '<code>image&gt;</code>' and '<code>font&gt;</code>'. Default protocol is 
+     * '<code>image&gt;</code>'. 
+     * 
+     * <p>The following are the examples of different graphic nodes:
+	 * <pre>
+	 * &#64;ActionProxy(text="Teacher", graphic="http://icons.iconarchive.com/icons/custom-icon-design/mini-3/16/teacher-male-icon.png")
+	 * &#64;ActionProxy(text="Security", graphic="/org/controlsfx/samples/security-low.png")
+	 * &#64;ActionProxy(text="Security", graphic="image&gt;/org/controlsfx/samples/security-low.png")
+	 * &#64;ActionProxy(text="Star", graphic="font&gt;FontAwesome|STAR")
+	 * </pre>     
+	 * 
+	 */
+    String graphic() default "";
+    
+    /**
+     * The text that should be set in {@link Action#longTextProperty()}.
+     */
+    String longText() default "";
+    
+    /**
+     * Accepts string values such as "ctrl+shift+T" to represent the keyboard
+     * shortcut for this action. By default this is empty if there is no keyboard
+     * shortcut desired for this action.
+     */
+    String accelerator() default "";
+    
+    /**
+     * The full class-name of a class that implements {@link AnnotatedActionFactory}. {@link ActionMap} will
+     * use this class to instantiate the {@link AnnotatedAction} associated with this method, rather than
+     * using its own action factory.
+     */
+    String factory() default "";
+}
diff --git a/src/org/controlsfx/control/action/ActionUtils.java b/src/org/controlsfx/control/action/ActionUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7169dcdb863cc45d335fa2cdbe2f25bfa2e4715
--- /dev/null
+++ b/src/org/controlsfx/control/action/ActionUtils.java
@@ -0,0 +1,890 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.action;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.binding.ObjectBinding;
+import javafx.beans.binding.StringBinding;
+import javafx.beans.binding.When;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.MapChangeListener;
+import javafx.collections.ObservableList;
+import javafx.css.Styleable;
+import javafx.scene.Node;
+import javafx.scene.control.*;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+import org.controlsfx.control.SegmentedButton;
+import org.controlsfx.tools.Duplicatable;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Convenience class for users of the {@link Action} API. Primarily this class
+ * is used to conveniently create UI controls from a given Action (this is
+ * necessary for now as there is no built-in support for Action in JavaFX
+ * UI controls at present).
+ *
+ * <p>Some of the methods in this class take a {@link Collection} of
+ * {@link Action actions}. In these cases, it is likely they are designed to
+ * work with {@link ActionGroup action groups}. For examples on how to work with
+ * these methods, refer to the {@link ActionGroup} class documentation.
+ *
+ * @see Action
+ * @see ActionGroup
+ */
+@SuppressWarnings("deprecation")
+public class ActionUtils {
+
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    private ActionUtils() {
+        // no-op
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Action API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Action text behavior.
+     * Defines uniform action's text behavior for multi-action controls such as toolbars and menus
+     */
+    public enum ActionTextBehavior {
+        /**
+         * Text is shown as usual on related control
+         */
+        SHOW,
+
+        /**
+         * Text is not shown on the related control
+         */
+        HIDE,
+    }
+
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link Button} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link Button} should bind to.
+     * @param textBehavior Defines {@link ActionTextBehavior}
+     * @return A {@link Button} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static Button createButton(final Action action, final ActionTextBehavior textBehavior) {
+        return configure(new Button(), action, textBehavior);
+    }
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link Button} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link Button} should bind to.
+     * @return A {@link Button} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static Button createButton(final Action action) {
+        return configure(new Button(), action, ActionTextBehavior.SHOW);
+    }
+
+    /**
+     * Takes the provided {@link Action} and binds the relevant properties to
+     * the supplied {@link Button}. This allows for the use of Actions
+     * within custom Button subclasses.
+     *
+     * @param action The {@link Action} that the {@link Button} should bind to.
+     * @param button The {@link ButtonBase} that the {@link Action} should be bound to.
+     * @return The {@link ButtonBase} that was bound to the {@link Action}.
+     */
+    public static ButtonBase configureButton(final Action action, ButtonBase button) {
+        return configure(button, action, ActionTextBehavior.SHOW);
+    }
+
+    /**
+     * Removes all bindings and listeners which were added when the supplied
+     * {@link ButtonBase} was bound to an {@link Action} via one of the methods
+     * of this class.
+     *
+     * @param button a {@link ButtonBase} that was bound to an {@link Action}
+     */
+    public static void unconfigureButton(ButtonBase button) {
+        unconfigure(button);
+    }
+	    
+    /**
+     * Takes the provided {@link Action} and returns a {@link MenuButton} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link MenuButton} should bind to.
+     * @param textBehavior Defines {@link ActionTextBehavior}
+     * @return A {@link MenuButton} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static MenuButton createMenuButton(final Action action, final ActionTextBehavior textBehavior) {
+        return configure(new MenuButton(), action, textBehavior);
+    }
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link MenuButton} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link MenuButton} should bind to.
+     * @return A {@link MenuButton} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static MenuButton createMenuButton(final Action action) {
+        return configure(new MenuButton(), action, ActionTextBehavior.SHOW);
+    }
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link Hyperlink} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link Hyperlink} should bind to.
+     * @return A {@link Hyperlink} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static Hyperlink createHyperlink(final Action action) {
+        return configure(new Hyperlink(), action, ActionTextBehavior.SHOW);
+    }
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link ToggleButton} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link ToggleButton} should bind to.
+     * @param textBehavior Defines {@link ActionTextBehavior}
+     * @return A {@link ToggleButton} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static ToggleButton createToggleButton(final Action action, final ActionTextBehavior textBehavior ) {
+        return configure(new ToggleButton(), action, textBehavior);
+    }
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link ToggleButton} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link ToggleButton} should bind to.
+     * @return A {@link ToggleButton} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static ToggleButton createToggleButton( final Action action ) {
+        return createToggleButton( action, ActionTextBehavior.SHOW );
+    }
+
+    /**
+     * Takes the provided {@link Collection} of {@link Action}  and returns a {@link SegmentedButton} instance
+     * with all relevant properties bound to the properties of the actions.
+     *
+     * @param actions The {@link Collection} of {@link Action} that the {@link SegmentedButton} should bind to.
+     * @param textBehavior Defines {@link ActionTextBehavior}
+     * @return A {@link SegmentedButton} that is bound to the state of the provided {@link Action}s
+     */
+    public static SegmentedButton createSegmentedButton(final ActionTextBehavior textBehavior, Collection<? extends Action> actions) {
+        ObservableList<ToggleButton> buttons = FXCollections.observableArrayList();
+        for( Action a: actions ) {
+            buttons.add( createToggleButton(a,textBehavior));
+        }
+        return new SegmentedButton( buttons );
+    }
+
+    /**
+     * Takes the provided {@link Collection} of {@link Action}  and returns a {@link SegmentedButton} instance
+     * with all relevant properties bound to the properties of the actions.
+     *
+     * @param actions The {@link Collection} of {@link Action} that the {@link SegmentedButton} should bind to.
+     * @return A {@link SegmentedButton} that is bound to the state of the provided {@link Action}s
+     */
+    public static SegmentedButton createSegmentedButton(Collection<? extends Action> actions) {
+        return createSegmentedButton( ActionTextBehavior.SHOW, actions);
+    }
+
+    /**
+     * Takes the provided varargs array of {@link Action}  and returns a {@link SegmentedButton} instance
+     * with all relevant properties bound to the properties of the actions.
+     *
+     * @param actions A varargs array of {@link Action} that the {@link SegmentedButton} should bind to.
+     * @param textBehavior Defines {@link ActionTextBehavior}
+     * @return A {@link SegmentedButton} that is bound to the state of the provided {@link Action}s
+     */
+    public static SegmentedButton createSegmentedButton(ActionTextBehavior textBehavior, Action... actions) {
+        return createSegmentedButton(textBehavior, Arrays.asList(actions));
+    }
+
+    /**
+     * Takes the provided varargs array of {@link Action}  and returns a {@link SegmentedButton} instance
+     * with all relevant properties bound to the properties of the actions.
+     *
+     * @param actions A varargs array of {@link Action} that the {@link SegmentedButton} should bind to.
+     * @return A {@link SegmentedButton} that is bound to the state of the provided {@link Action}s
+     */
+    public static SegmentedButton createSegmentedButton(Action... actions) {
+        return createSegmentedButton(ActionTextBehavior.SHOW, Arrays.asList(actions));
+    }
+
+
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link CheckBox} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link CheckBox} should bind to.
+     * @return A {@link CheckBox} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static CheckBox createCheckBox(final Action action) {
+        return configure(new CheckBox(), action, ActionTextBehavior.SHOW);
+    }
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link RadioButton} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link RadioButton} should bind to.
+     * @return A {@link RadioButton} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static RadioButton createRadioButton(final Action action) {
+        return configure(new RadioButton(), action, ActionTextBehavior.SHOW);
+    }
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link MenuItem} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link MenuItem} should bind to.
+     * @return A {@link MenuItem} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static MenuItem createMenuItem(final Action action) {
+
+        MenuItem menuItem =
+            action.getClass().isAnnotationPresent(ActionCheck.class)? new CheckMenuItem(): new MenuItem();
+
+        return configure( menuItem, action);
+    }
+
+    public static MenuItem configureMenuItem(final Action action, MenuItem menuItem) {
+        return configure(menuItem, action);
+    }
+
+    /**
+     * Removes all bindings and listeners which were added when the supplied
+     * {@link MenuItem} was bound to an {@link Action} via one of the methods
+     * of this class.
+     *
+     * @param menuItem a {@link MenuItem} that was bound to an {@link Action}
+     */
+    public static void unconfigureMenuItem(final MenuItem menuItem) {
+        unconfigure(menuItem);
+    }
+    
+    /**
+     * Takes the provided {@link Action} and returns a {@link Menu} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link Menu} should bind to.
+     * @return A {@link Menu} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static Menu createMenu(final Action action) {
+        return configure(new Menu(), action);
+    }
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link CheckMenuItem} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link CheckMenuItem} should bind to.
+     * @return A {@link CheckMenuItem} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static CheckMenuItem createCheckMenuItem(final Action action) {
+        return configure(new CheckMenuItem(), action);
+    }
+
+    /**
+     * Takes the provided {@link Action} and returns a {@link RadioMenuItem} instance
+     * with all relevant properties bound to the properties of the Action.
+     *
+     * @param action The {@link Action} that the {@link RadioMenuItem} should bind to.
+     * @return A {@link RadioMenuItem} that is bound to the state of the provided
+     *      {@link Action}
+     */
+    public static RadioMenuItem createRadioMenuItem(final Action action) {
+        return configure(new RadioMenuItem(action.textProperty().get()), action);
+    }
+
+
+
+    /***************************************************************************
+     *                                                                         *
+     * ActionGroup API                                                         *
+     *                                                                         *
+     **************************************************************************/
+
+
+    /**
+     * Action representation of the generic separator. Adding this action anywhere in the
+     * action tree serves as indication that separator has be created in its place.
+     * See {@link ActionGroup} for example of action tree creation
+     */
+    public static Action ACTION_SEPARATOR = new Action(null, null) {
+        @Override public String toString() {
+            return "Separator";  //$NON-NLS-1$
+        }
+    };
+
+    public static Action ACTION_SPAN = new Action(null, null) {
+        @Override public String toString() {
+            return "Span";  //$NON-NLS-1$
+        }
+    };
+
+
+
+    /**
+     * Takes the provided {@link Collection} of {@link Action} (or subclasses,
+     * such as {@link ActionGroup}) instances and returns a {@link ToolBar}
+     * populated with appropriate {@link Node nodes} bound to the provided
+     * {@link Action actions}.
+     *
+     * @param actions The {@link Action actions} to place on the {@link ToolBar}.
+     * @param textBehavior defines {@link ActionTextBehavior}
+     * @return A {@link ToolBar} that contains {@link Node nodes} which are bound
+     *      to the state of the provided {@link Action}
+     */
+    public static ToolBar createToolBar(Collection<? extends Action> actions, ActionTextBehavior textBehavior) {
+        return updateToolBar( new ToolBar(), actions, textBehavior );
+    }
+
+    /**
+     * Takes the provided {@link Collection} of {@link Action} (or subclasses,
+     * such as {@link ActionGroup}) instances and returns provided {@link ToolBar}
+     * populated with appropriate {@link Node nodes} bound to the provided
+     * {@link Action actions}. Previous toolbar content is removed
+     *
+     * @param toolbar The {@link ToolBar toolbar} to update
+     * @param actions The {@link Action actions} to place on the {@link ToolBar}.
+     * @param textBehavior defines {@link ActionTextBehavior}
+     * @return A {@link ToolBar} that contains {@link Node nodes} which are bound
+     *      to the state of the provided {@link Action}
+     */
+    public static ToolBar updateToolBar( ToolBar toolbar, Collection<? extends Action> actions, ActionTextBehavior textBehavior) {
+        toolbar.getItems().clear();
+        for (Action action : actions) {
+            if ( action instanceof ActionGroup ) {
+                MenuButton menu = createMenuButton( action, textBehavior );
+                menu.setFocusTraversable(false);
+                menu.getItems().addAll( toMenuItems( ((ActionGroup)action).getActions()));
+                toolbar.getItems().add(menu);
+            } else if ( action == ACTION_SEPARATOR ) {
+                toolbar.getItems().add( new Separator());
+            } else if ( action == ACTION_SPAN ) {
+                Pane span = new Pane();
+                HBox.setHgrow(span, Priority.ALWAYS);
+                VBox.setVgrow(span, Priority.ALWAYS);
+                toolbar.getItems().add(span);
+            } else if ( action == null ) {
+                //no-op
+            } else {
+
+                ButtonBase button;
+                if ( action.getClass().getAnnotation(ActionCheck.class) != null ) {
+                    button = createToggleButton(action, textBehavior);
+                } else {
+                    button = createButton(action, textBehavior);
+                }
+                button.setFocusTraversable(false);
+                toolbar.getItems().add(button);
+            }
+        }
+
+        return toolbar;
+    }
+
+    /**
+     * Takes the provided {@link Collection} of {@link Action} (or subclasses,
+     * such as {@link ActionGroup}) instances and returns a {@link MenuBar}
+     * populated with appropriate {@link Node nodes} bound to the provided
+     * {@link Action actions}.
+     *
+     * @param actions The {@link Action actions} to place on the {@link MenuBar}.
+     * @return A {@link MenuBar} that contains {@link Node nodes} which are bound
+     *      to the state of the provided {@link Action}
+     */
+    public static MenuBar createMenuBar(Collection<? extends Action> actions) {
+        return updateMenuBar(new MenuBar(), actions);
+    }
+
+    /**
+     * Takes the provided {@link Collection} of {@link Action} (or subclasses,
+     * such as {@link ActionGroup}) instances and updates a {@link MenuBar}
+     * populated with appropriate {@link Node nodes} bound to the provided
+     * {@link Action actions}. Previous MenuBar content is removed.
+     *
+     * @param menuBar The {@link MenuBar menuBar} to update
+     * @param actions The {@link Action actions} to place on the {@link MenuBar}.
+     * @return A {@link MenuBar} that contains {@link Node nodes} which are bound
+     *      to the state of the provided {@link Action}
+     */
+    public static MenuBar updateMenuBar( MenuBar menuBar, Collection<? extends Action> actions) {
+        menuBar.getMenus().clear();
+        for (Action action : actions) {
+
+            if ( action == ACTION_SEPARATOR || action == ACTION_SPAN ) continue;
+
+            Menu menu = createMenu( action );
+
+            if ( action instanceof ActionGroup ) {
+                menu.getItems().addAll( toMenuItems( ((ActionGroup)action).getActions()));
+            } else if ( action == null ) {
+                //no-op
+            }
+
+            menuBar.getMenus().add(menu);
+        }
+
+        return menuBar;
+    }
+
+    /**
+     * Takes the provided {@link Collection} of {@link Action} (or subclasses,
+     * such as {@link ActionGroup}) instances and returns a {@link ButtonBar}
+     * populated with appropriate {@link Node nodes} bound to the provided
+     * {@link Action actions}.
+     *
+     * @param actions The {@link Action actions} to place on the {@link ButtonBar}.
+     * @return A {@link ButtonBar} that contains {@link Node nodes} which are bound
+     *      to the state of the provided {@link Action}
+     */
+    public static ButtonBar createButtonBar(Collection<? extends Action> actions) {
+        return updateButtonBar( new ButtonBar(), actions);
+    }
+
+    /**
+     * Takes the provided {@link Collection} of {@link Action} (or subclasses,
+     * such as {@link ActionGroup}) instances and updates a {@link ButtonBar}
+     * populated with appropriate {@link Node nodes} bound to the provided
+     * {@link Action actions}. Previous content of button bar is removed
+     *
+     * @param buttonBar The {@link ButtonBar buttonBar} to update
+     * @param actions The {@link Action actions} to place on the {@link ButtonBar}.
+     * @return A {@link ButtonBar} that contains {@link Node nodes} which are bound
+     *      to the state of the provided {@link Action}
+     */
+    public static ButtonBar updateButtonBar( ButtonBar buttonBar, Collection<? extends Action> actions) {
+        buttonBar.getButtons().clear();
+        for (Action action : actions) {
+            if ( action instanceof ActionGroup ) {
+                // no-op
+            } else if ( action == ACTION_SPAN || action == ACTION_SEPARATOR || action == null ) {
+                // no-op
+            } else {
+                buttonBar.getButtons().add(createButton(action, ActionTextBehavior.SHOW));
+            }
+        }
+
+        return buttonBar;
+    }
+
+    /**
+     * Takes the provided {@link Collection} of {@link Action} (or subclasses,
+     * such as {@link ActionGroup}) instances and returns a {@link ContextMenu}
+     * populated with appropriate {@link Node nodes} bound to the provided
+     * {@link Action actions}.
+     *
+     * @param actions The {@link Action actions} to place on the {@link ContextMenu}.
+     * @return A {@link ContextMenu} that contains {@link Node nodes} which are bound
+     *      to the state of the provided {@link Action}
+     */
+    public static ContextMenu createContextMenu(Collection<? extends Action> actions) {
+        return updateContextMenu(new ContextMenu(), actions);
+    }
+
+    /**
+     * Takes the provided {@link Collection} of {@link Action} (or subclasses,
+     * such as {@link ActionGroup}) instances and updates a {@link ContextMenu}
+     * populated with appropriate {@link Node nodes} bound to the provided
+     * {@link Action actions}. Previous content of context menu is removed
+     *
+     * @param menu The {@link ContextMenu menu} to update
+     * @param actions The {@link Action actions} to place on the {@link ContextMenu}.
+     * @return A {@link ContextMenu} that contains {@link Node nodes} which are bound
+     *      to the state of the provided {@link Action}
+     */
+    public static ContextMenu updateContextMenu(ContextMenu menu, Collection<? extends Action> actions) {
+        menu.getItems().clear();
+        menu.getItems().addAll(toMenuItems(actions));
+        return menu;
+    }
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Private implementation                                                  *
+     *                                                                         *
+     **************************************************************************/
+
+    private static Collection<MenuItem> toMenuItems( Collection<? extends Action> actions ) {
+
+        Collection<MenuItem> items = new ArrayList<>();
+
+        for (Action action : actions) {
+
+            if ( action instanceof ActionGroup ) {
+
+                Menu menu = createMenu( action );
+                menu.getItems().addAll( toMenuItems( ((ActionGroup)action).getActions()));
+                items.add(menu);
+
+            } else if ( action == ACTION_SEPARATOR ) {
+
+                items.add( new SeparatorMenuItem());
+
+            } else if ( action == null || action == ACTION_SPAN) {
+                // no-op
+            } else {
+
+                items.add( createMenuItem(action));
+
+            }
+
+        }
+
+        return items;
+
+    }
+
+    private static Node copyNode( Node node ) {
+        if ( node instanceof ImageView ) {
+            return new ImageView( ((ImageView)node).getImage());
+        } else if ( node instanceof Duplicatable<?> ) {
+            return (Node) ((Duplicatable<?>)node).duplicate();
+        } else {
+            return null;
+        }
+    }
+
+    // Carry over action style classes changes to the styleable
+    // Binding as not a good solution since it wipes out existing styleable classes
+    private static void bindStyle(final Styleable styleable, final Action action ) {
+        styleable.getStyleClass().addAll( action.getStyleClass() );
+        action.getStyleClass().addListener(new ListChangeListener<String>() {
+            @Override
+            public void onChanged(Change<? extends String> c) {
+                while(c.next()) {
+                    if (c.wasRemoved()) {
+                        styleable.getStyleClass().removeAll(c.getRemoved());
+                    }
+                    if (c.wasAdded()) {
+                        styleable.getStyleClass().addAll(c.getAddedSubList());
+                    }
+                }
+            }
+        });
+    }
+
+    private static <T extends ButtonBase> T configure(final T btn, final Action action, final ActionTextBehavior textBehavior) {
+        if (action == null) {
+            throw new NullPointerException("Action can not be null"); //$NON-NLS-1$
+        }
+
+        // button bind to action properties
+
+        bindStyle(btn,action);
+
+        //btn.textProperty().bind(action.textProperty());
+        if ( textBehavior == ActionTextBehavior.SHOW ) {
+            btn.textProperty().bind(action.textProperty());
+        }
+        btn.disableProperty().bind(action.disabledProperty());
+
+
+        btn.graphicProperty().bind(new ObjectBinding<Node>() {
+            { bind(action.graphicProperty()); }
+
+            @Override protected Node computeValue() {
+                return copyNode(action.graphicProperty().get());
+            }
+
+            @Override
+            public void removeListener(InvalidationListener listener) {
+                super.removeListener(listener);
+                unbind(action.graphicProperty());
+            }
+        });
+
+
+        // add all the properties of the action into the button, and set up
+        // a listener so they are always copied across
+        btn.getProperties().putAll(action.getProperties());
+        action.getProperties().addListener(new ButtonPropertiesMapChangeListener<>(btn, action));
+
+        // tooltip requires some special handling (i.e. don't have one when
+        // the text property is null
+        btn.tooltipProperty().bind(new ObjectBinding<Tooltip>() {
+            private Tooltip tooltip = new Tooltip();
+            private StringBinding textBinding = new When(action.longTextProperty().isEmpty()).then(action.textProperty()).otherwise(action.longTextProperty());
+
+            {
+                bind(textBinding);
+                tooltip.textProperty().bind(textBinding);
+            }
+
+            @Override protected Tooltip computeValue() {
+                String longText =  textBinding.get();
+                return longText == null || textBinding.get().isEmpty() ? null : tooltip;
+            }
+
+            @Override
+            public void removeListener(InvalidationListener listener) {
+                super.removeListener(listener);
+                unbind(action.longTextProperty());
+                tooltip.textProperty().unbind();
+            }
+        });
+
+
+
+        // Handle the selected state of the button if it is of the applicable type
+
+        if ( btn instanceof ToggleButton ) {
+            ((ToggleButton)btn).selectedProperty().bindBidirectional(action.selectedProperty());
+        }
+
+        // Just call the execute method on the action itself when the action
+        // event occurs on the button
+        btn.setOnAction(action);
+
+        return btn;
+    }
+
+    private static void unconfigure(final ButtonBase btn) {
+        if (btn == null || !(btn.getOnAction() instanceof Action)) {
+            return;
+        }
+
+        Action action = (Action) btn.getOnAction();
+
+        btn.styleProperty().unbind();
+        btn.textProperty().unbind();
+        btn.disableProperty().unbind();
+        btn.graphicProperty().unbind();
+
+        action.getProperties().removeListener(new ButtonPropertiesMapChangeListener<>(btn, action));
+
+        btn.tooltipProperty().unbind();
+
+        if (btn instanceof ToggleButton) {
+            ((ToggleButton) btn).selectedProperty().unbindBidirectional(action.selectedProperty());
+        }
+
+        btn.setOnAction(null);
+    }
+    
+    private static <T extends MenuItem> T configure(final T menuItem, final Action action) {
+        if (action == null) {
+            throw new NullPointerException("Action can not be null"); //$NON-NLS-1$
+        }
+
+        // button bind to action properties
+        bindStyle(menuItem,action);
+
+        menuItem.textProperty().bind(action.textProperty());
+        menuItem.disableProperty().bind(action.disabledProperty());
+        menuItem.acceleratorProperty().bind(action.acceleratorProperty());
+
+        menuItem.graphicProperty().bind(new ObjectBinding<Node>() {
+            { bind(action.graphicProperty()); }
+
+            @Override protected Node computeValue() {
+                return copyNode( action.graphicProperty().get());
+            }
+
+            @Override
+            public void removeListener(InvalidationListener listener) {
+                super.removeListener(listener);
+                unbind(action.graphicProperty());
+            }
+        });
+
+
+        // add all the properties of the action into the button, and set up
+        // a listener so they are always copied across
+        menuItem.getProperties().putAll(action.getProperties());
+        action.getProperties().addListener(new MenuItemPropertiesMapChangeListener<>(menuItem, action));
+
+        // Handle the selected state of the menu item if it is a
+        // CheckMenuItem or RadioMenuItem
+
+        if ( menuItem instanceof RadioMenuItem ) {
+            ((RadioMenuItem)menuItem).selectedProperty().bindBidirectional(action.selectedProperty());
+        } else if ( menuItem instanceof CheckMenuItem ) {
+            ((CheckMenuItem)menuItem).selectedProperty().bindBidirectional(action.selectedProperty());
+        }
+
+        // Just call the execute method on the action itself when the action
+        // event occurs on the button
+        menuItem.setOnAction(action);
+
+        return menuItem;
+    }
+
+    private static void unconfigure(final MenuItem menuItem) {
+        if (menuItem == null || !(menuItem.getOnAction() instanceof Action)) {
+            return;
+        }
+
+        Action action = (Action) menuItem.getOnAction();
+
+        menuItem.styleProperty().unbind();
+        menuItem.textProperty().unbind();
+        menuItem.disableProperty().unbind();
+        menuItem.acceleratorProperty().unbind();
+        menuItem.graphicProperty().unbind();
+
+        action.getProperties().removeListener(new MenuItemPropertiesMapChangeListener<>(menuItem, action));
+
+        if (menuItem instanceof RadioMenuItem) {
+            ((RadioMenuItem) menuItem).selectedProperty().unbindBidirectional(action.selectedProperty());
+        } else if (menuItem instanceof CheckMenuItem) {
+            ((CheckMenuItem) menuItem).selectedProperty().unbindBidirectional(action.selectedProperty());
+        }
+
+        menuItem.setOnAction(null);
+    }
+
+    private static class ButtonPropertiesMapChangeListener<T extends ButtonBase> implements MapChangeListener<Object, Object> {
+
+        private final WeakReference<T> btnWeakReference;
+        private final Action action;
+
+        private ButtonPropertiesMapChangeListener(T btn, Action action) {
+            btnWeakReference = new WeakReference<>(btn);
+            this.action = action;
+        }
+
+        @Override public void onChanged(MapChangeListener.Change<?, ?> change) {
+            T btn = btnWeakReference.get();
+            if (btn == null) {
+                action.getProperties().removeListener(this);
+            } else {
+                btn.getProperties().clear();
+                btn.getProperties().putAll(action.getProperties());
+            }
+        }
+
+        @Override
+        public boolean equals(Object otherObject) {
+            if (this == otherObject) {
+                return true;
+            }
+            if (otherObject == null || getClass() != otherObject.getClass()) {
+                return false;
+            }
+
+            ButtonPropertiesMapChangeListener<?> otherListener = (ButtonPropertiesMapChangeListener<?>) otherObject;
+
+            T btn = btnWeakReference.get();
+            ButtonBase otherBtn = otherListener.btnWeakReference.get();
+            if (btn != null ? !btn.equals(otherBtn) : otherBtn != null) {
+                return false;
+            }
+            return action.equals(otherListener.action);
+        }
+
+        @Override
+        public int hashCode() {
+            T btn = btnWeakReference.get();
+            int result = btn != null ? btn.hashCode() : 0;
+            result = 31 * result + action.hashCode();
+            return result;
+        }
+    }
+
+    private static class MenuItemPropertiesMapChangeListener<T extends MenuItem> implements MapChangeListener<Object, Object> {
+
+        private final WeakReference<T> menuItemWeakReference;
+        private final Action action;
+
+        private MenuItemPropertiesMapChangeListener(T menuItem, Action action) {
+            menuItemWeakReference = new WeakReference<>(menuItem);
+            this.action = action;
+        }
+
+        @Override public void onChanged(MapChangeListener.Change<?, ?> change) {
+            T menuItem = menuItemWeakReference.get();
+            if (menuItem == null) {
+                action.getProperties().removeListener(this);
+            } else {
+                menuItem.getProperties().clear();
+                menuItem.getProperties().putAll(action.getProperties());
+            }
+        }
+
+        @Override
+        public boolean equals(Object otherObject) {
+            if (this == otherObject) {
+                return true;
+            }
+            if (otherObject == null || getClass() != otherObject.getClass()) {
+                return false;
+            }
+
+            MenuItemPropertiesMapChangeListener<?> otherListener = (MenuItemPropertiesMapChangeListener<?>) otherObject;
+
+            T menuItem = menuItemWeakReference.get();
+            MenuItem otherMenuItem = otherListener.menuItemWeakReference.get();
+            return menuItem != null ? menuItem.equals(otherMenuItem) : otherMenuItem == null && action.equals(otherListener.action);
+
+        }
+
+        @Override
+        public int hashCode() {
+            T menuItem = menuItemWeakReference.get();
+            int result = menuItem != null ? menuItem.hashCode() : 0;
+            result = 31 * result + action.hashCode();
+            return result;
+        }
+    }
+}
diff --git a/src/org/controlsfx/control/action/AnnotatedAction.java b/src/org/controlsfx/control/action/AnnotatedAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..b667cda1f52462dec26f2fab262e76d9ce05d797
--- /dev/null
+++ b/src/org/controlsfx/control/action/AnnotatedAction.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.action;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.util.Objects;
+import javafx.event.ActionEvent;
+
+
+
+/**
+ * An action that invokes a method that has been annotated with {@link ActionProxy}. These actions are created via
+ * {@link ActionMap#register(java.lang.Object)}, which delegates the actual instantiation to an {@link AnnotatedActionFactory}.
+ * 
+ * Note that this class maintains a WeakReference to the supplied target object, so the existence of an 
+ * AnnotatedAction instance will not prevent the target from being garbage-collected.
+ */
+public class AnnotatedAction extends Action {
+
+    private final Method method;
+    private final WeakReference<Object> target;
+
+    /**
+     * Instantiates an action that will call the specified method on the specified target.
+     */
+    public AnnotatedAction(String text, Method method, Object target) {
+        super(text);
+        Objects.requireNonNull( method );
+        Objects.requireNonNull( target );
+        
+        setEventHandler(this::handleAction);
+        
+        this.method = method;
+        this.method.setAccessible(true);
+        this.target = new WeakReference( target );
+    }
+    
+    /**
+     * Returns the target object (the object on which the annotated method will be called).
+     * 
+     * @return The target object, or null if the target object has been garbage-collected.
+     */
+    public Object getTarget() {
+        return target.get();
+    }
+
+    /**
+     * Handle the action-event by invoking the annotated method on the target object. If an exception is
+     * thrown, then the default implementation of this method will call handleActionException().
+     */
+    protected void handleAction(ActionEvent ae) {
+        try {
+            Object actionTarget = getTarget();
+            if (actionTarget == null) {
+                throw new IllegalStateException( "Action target object is no longer reachable" );
+            }
+            
+            int paramCount =  method.getParameterCount(); 
+            if ( paramCount == 0 ) {
+                method.invoke(actionTarget);
+                
+            } else if ( paramCount == 1) {
+                method.invoke(actionTarget, ae);
+                
+            } else if ( paramCount == 2) {
+                method.invoke(actionTarget, ae, this);
+            }
+        } catch (Throwable e) {
+            handleActionException( ae, e );
+        }
+    }
+    
+    
+    /**
+     * Called if the annotated method throws an exception when invoked. The default implementation of this method simply prints
+     * the stack trace of the specified exception.
+     */
+    protected void handleActionException( ActionEvent ae, Throwable ex ) {
+        ex.printStackTrace();
+    }
+    
+    
+    /**
+     * Overridden to return the text of this action.
+     */
+    @Override
+    public String toString() {
+        return getText();
+    }
+}
diff --git a/src/org/controlsfx/control/action/AnnotatedActionFactory.java b/src/org/controlsfx/control/action/AnnotatedActionFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c083de16a08e2d11b39714ba5b965e3caa575d4
--- /dev/null
+++ b/src/org/controlsfx/control/action/AnnotatedActionFactory.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.action;
+
+import java.lang.reflect.Method;
+
+
+/**
+ * Defines the interface used by {@link ActionMap} for creating instances of {@link AnnotatedAction}.
+ */
+public interface AnnotatedActionFactory {
+
+    /**
+     * Create an {@link AnnotatedAction} instance.
+     * 
+     * @param annotation The annotation specified on the method.
+     * @param method The method to be invoked when an action is fired.
+     * @param target The target object on which the method will be invoked.
+     * @return An {@link AnnotatedAction} instance.
+     */
+    AnnotatedAction createAction( ActionProxy annotation, Method method, Object target );
+}
diff --git a/src/org/controlsfx/control/action/AnnotatedCheckAction.java b/src/org/controlsfx/control/action/AnnotatedCheckAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..5b5dfd390a3afb4dcc8645112378b90ebbd71586
--- /dev/null
+++ b/src/org/controlsfx/control/action/AnnotatedCheckAction.java
@@ -0,0 +1,19 @@
+package org.controlsfx.control.action;
+
+import java.lang.reflect.Method;
+
+@ActionCheck
+public class AnnotatedCheckAction extends AnnotatedAction {
+
+    /**
+     * Instantiates an action that will call the specified method on the specified target.
+     * This action is marked  with @ActionCheck
+     *
+     * @param text
+     * @param method
+     * @param target
+     */
+    public AnnotatedCheckAction(String text, Method method, Object target) {
+        super(text, method, target);
+    }
+}
diff --git a/src/org/controlsfx/control/action/DefaultActionFactory.java b/src/org/controlsfx/control/action/DefaultActionFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..3dc3d3199b37428efa06a5f20a3f787f870e198a
--- /dev/null
+++ b/src/org/controlsfx/control/action/DefaultActionFactory.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.action;
+
+import javafx.scene.Node;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.KeyCombination;
+import org.controlsfx.glyphfont.Glyph;
+
+import java.lang.reflect.Method;
+
+/**
+ * The default {@link AnnotatedActionFactory} to be used when no alternative has been specified. This class creates
+ * instances of {@link AnnotatedAction}.
+ */
+public class DefaultActionFactory implements AnnotatedActionFactory {
+
+    /**
+     * Create an {@link AnnotatedAction}. This method is called by {@link ActionMap#register(java.lang.Object)}.
+     * 
+     * @param annotation The annotation specified on the method.
+     * @param method The method to be invoked when an action is fired.
+     * @param target The target object on which the method will be invoked.
+     * @return An {@link AnnotatedAction} instance.
+     */
+    @Override
+    public AnnotatedAction createAction( ActionProxy annotation, Method method, Object target ) {
+        AnnotatedAction action;
+        if ( method.isAnnotationPresent(ActionCheck.class)) {
+            action = new AnnotatedCheckAction(annotation.text(), method, target);
+        } else {
+            action = new AnnotatedAction(annotation.text(), method, target);
+        }
+        
+        configureAction( annotation, action );
+        
+        return action;
+    }
+    
+    
+    /**
+     * Configures the newly-created action before it is returned to {@link ActionMap}. Subclasses can override this method
+     * to change configuration behavior.
+     * 
+     * @param annotation The annotation specified on the method.
+     * @param action The newly-created action.
+     */
+    protected void configureAction( ActionProxy annotation, AnnotatedAction action ) {
+        Node graphic = resolveGraphic(annotation);
+        action.setGraphic(graphic);
+        
+        // set long text / tooltip
+        String longText = annotation.longText().trim();
+        if ( graphic != null ) {
+            action.setLongText(longText);
+        }
+        
+        // set accelerator
+        String acceleratorText = annotation.accelerator().trim();
+        if (!acceleratorText.isEmpty()) {
+            action.setAccelerator(KeyCombination.keyCombination(acceleratorText));
+        }
+
+    }
+    
+    
+    /**
+     * Resolve the graphical representation of this action. The default implementation of this method implements the protocol described
+     * in {@link ActionProxy#graphic()}, but subclasses can override this method to provide alternative behavior.
+     * 
+     * @param annotation The annotation specified on the method.
+     * @return A JavaFX Node for the graphic associated with this action.
+     */
+    protected Node resolveGraphic( ActionProxy annotation ) {
+        String graphicDef = annotation.graphic().trim();
+        if ( !graphicDef.isEmpty()) {
+            
+            String[] def = graphicDef.split("\\>");  // cannot use ':' because it used in urls //$NON-NLS-1$
+            if ( def.length == 1 ) return new ImageView(new Image(def[0]));
+            switch (def[0]) {
+               case "font"    : return Glyph.create(def[1]);   //$NON-NLS-1$
+               case "image"   : return new ImageView(new Image(def[1])); //$NON-NLS-1$
+               default: throw new IllegalArgumentException( String.format("Unknown ActionProxy graphic protocol: %s", def[0])); //$NON-NLS-1$
+            }
+        }
+        return null;
+    }
+    
+}
diff --git a/src/org/controlsfx/control/action/package-info.java b/src/org/controlsfx/control/action/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..bcb828d425e564dfcde8f989a9faac66410fa1a3
--- /dev/null
+++ b/src/org/controlsfx/control/action/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * A package containing the {@link org.controlsfx.control.action.Action} API, as well
+ * as the {@link org.controlsfx.control.action.Action} convenience subclass. 
+ * Refer to these two classes for the necessary details on what actions are in
+ * the JavaFX context.
+ */
+package org.controlsfx.control.action;
\ No newline at end of file
diff --git a/src/org/controlsfx/control/breadcrumbbar.css b/src/org/controlsfx/control/breadcrumbbar.css
new file mode 100644
index 0000000000000000000000000000000000000000..18ba30718467255358c4d4dab15b24b498d71c76
--- /dev/null
+++ b/src/org/controlsfx/control/breadcrumbbar.css
@@ -0,0 +1,3 @@
+.bread-crumb-bar {
+	
+}
diff --git a/src/org/controlsfx/control/cell/ColorGridCell.java b/src/org/controlsfx/control/cell/ColorGridCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..7317ccf75397d3363ad8aa8d3448ecdf0ce62b2b
--- /dev/null
+++ b/src/org/controlsfx/control/cell/ColorGridCell.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.cell;
+
+import javafx.scene.control.ContentDisplay;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+
+import org.controlsfx.control.GridCell;
+import org.controlsfx.control.GridView;
+
+/**
+ * A {@link GridCell} that can be used to show coloured rectangles inside the 
+ * {@link GridView} control.
+ *
+ * @see GridView
+ */
+public class ColorGridCell extends GridCell<Color> {
+	
+	private Rectangle colorRect;
+	
+	private static final boolean debug = false;
+
+	/**
+	 * Creates a default ColorGridCell instance.
+	 */
+    public ColorGridCell() {
+		getStyleClass().add("color-grid-cell"); //$NON-NLS-1$
+		
+		colorRect = new Rectangle();
+		colorRect.setStroke(Color.BLACK);
+		colorRect.heightProperty().bind(heightProperty());
+		colorRect.widthProperty().bind(widthProperty());   
+		setGraphic(colorRect);
+		
+		if (debug) {
+		    setContentDisplay(ContentDisplay.TEXT_ONLY);
+		}
+	}
+	
+    /**
+     * {@inheritDoc}
+     */
+	@Override protected void updateItem(Color item, boolean empty) {
+	    super.updateItem(item, empty);
+	    
+	    if (empty) {
+	        setGraphic(null);
+	    } else {
+	        colorRect.setFill(item);
+	        setGraphic(colorRect);
+	    }
+	    
+	    if (debug) {
+	        setText(getIndex() + ""); //$NON-NLS-1$
+	    }
+	}
+}
diff --git a/src/org/controlsfx/control/cell/ImageGridCell.java b/src/org/controlsfx/control/cell/ImageGridCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..7703f30ae58a40ae91c69f80fda95fef879c8a23
--- /dev/null
+++ b/src/org/controlsfx/control/cell/ImageGridCell.java
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.cell;
+
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+
+import org.controlsfx.control.GridCell;
+import org.controlsfx.control.GridView;
+
+/**
+ * A {@link GridCell} that can be used to show images inside the 
+ * {@link GridView} control.
+ *
+ * @see GridView
+ */
+public class ImageGridCell extends GridCell<Image> {
+	
+    private final ImageView imageView;
+    
+    private final boolean preserveImageProperties;
+    
+    
+    /**
+     * Creates a default ImageGridCell instance, which will preserve image properties
+     */
+    public ImageGridCell() {
+        this(true);
+    }
+    
+    /**
+     * Create ImageGridCell instance
+     * @param preserveImageProperties if set to true will preserve image aspect ratio and smoothness
+     */
+	public ImageGridCell( boolean preserveImageProperties ) {
+		getStyleClass().add("image-grid-cell"); //$NON-NLS-1$
+		
+		this.preserveImageProperties = preserveImageProperties;
+		imageView = new ImageView();
+        imageView.fitHeightProperty().bind(heightProperty());
+        imageView.fitWidthProperty().bind(widthProperty());
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override protected void updateItem(Image item, boolean empty) {
+	    super.updateItem(item, empty);
+	    
+	    if (empty) {
+	        setGraphic(null);
+	    } else {
+	        if (preserveImageProperties) {
+    	        imageView.setPreserveRatio(item.isPreserveRatio());
+    	        imageView.setSmooth( item.isSmooth());
+	        }
+	        imageView.setImage(item);
+	        setGraphic(imageView);
+	    }
+	}
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/cell/MediaImageCell.java b/src/org/controlsfx/control/cell/MediaImageCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..45648720b2910cf35d974c3f6f9061560208bd93
--- /dev/null
+++ b/src/org/controlsfx/control/cell/MediaImageCell.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.cell;
+
+import javafx.scene.media.Media;
+import javafx.scene.media.MediaPlayer;
+import javafx.scene.media.MediaView;
+
+import org.controlsfx.control.GridCell;
+import org.controlsfx.control.GridView;
+
+/**
+ * A {@link GridCell} that can be used to show media (i.e. movies) inside the 
+ * {@link GridView} control.
+ *
+ * @see GridView
+ */
+public class MediaImageCell extends GridCell<Media> {
+	
+	private MediaPlayer mediaPlayer;
+	private final MediaView mediaView;
+	
+	/**
+	 * Creates a default MediaGridCell instance.
+	 */
+	public MediaImageCell() {
+		getStyleClass().add("media-grid-cell"); //$NON-NLS-1$
+		
+		mediaView = new MediaView();
+		mediaView.setMediaPlayer(mediaPlayer);
+        mediaView.fitHeightProperty().bind(heightProperty());
+        mediaView.fitWidthProperty().bind(widthProperty());
+        mediaView.setMediaPlayer(mediaPlayer);
+	}
+	
+	/**
+	 * Pauses the media player inside this cell.
+	 */
+	public void pause() {
+		if(mediaPlayer != null) {
+			mediaPlayer.pause();
+		}
+	}
+	
+	/**
+     * Starts playing the media player inside this cell.
+     */
+	public void play() {
+		if(mediaPlayer != null) {
+			mediaPlayer.play();
+		}
+	}
+	
+	/**
+     * Stops playing the media player inside this cell.
+     */
+	public void stop() {
+		if(mediaPlayer != null) {
+			mediaPlayer.stop();
+		}
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override protected void updateItem(Media item, boolean empty) {
+	    super.updateItem(item, empty);
+	    
+	    getChildren().clear();
+        if (mediaPlayer != null) {
+            mediaPlayer.stop();
+        }
+	    
+	    if (empty) {
+	        setGraphic(null);
+	    } else {
+	        mediaPlayer = new MediaPlayer(item);
+	        mediaView.setMediaPlayer(mediaPlayer);
+	        setGraphic(mediaView);
+	    }
+	}
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/cell/package-info.java b/src/org/controlsfx/control/cell/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..430500695f7836d7a93ff3d5d33c302771cd0d3d
--- /dev/null
+++ b/src/org/controlsfx/control/cell/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * A package containing a number of useful cell-related classes that do not
+ * exist in the base JavaFX distribution, many related to the new 
+ * {@link org.controlsfx.control.GridView GridView} control offered in 
+ * ControlsFX.
+ * 
+ * @see org.controlsfx.control.GridView
+ */
+package org.controlsfx.control.cell;
\ No newline at end of file
diff --git a/src/org/controlsfx/control/collapse.png b/src/org/controlsfx/control/collapse.png
new file mode 100644
index 0000000000000000000000000000000000000000..b8896c70d7c216137b48d95a346c37f59a7b9588
Binary files /dev/null and b/src/org/controlsfx/control/collapse.png differ
diff --git a/src/org/controlsfx/control/decoration/Decoration.java b/src/org/controlsfx/control/decoration/Decoration.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5ff9867e7f94e48456ee7f0f1f2f6a6e38dc374
--- /dev/null
+++ b/src/org/controlsfx/control/decoration/Decoration.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.decoration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javafx.scene.Node;
+
+/**
+ * Decoration is an abstract class used by the ControlsFX {@link Decorator} class
+ * for adding and removing decorations on a node. ControlsFX
+ * ships with pre-built decorations, including {@link GraphicDecoration} and
+ * {@link StyleClassDecoration}.
+ * 
+ * <p>To better understand how to use the ControlsFX decoration API in your 
+ * application, refer to the code samples and explanations in {@link Decorator}.
+ * 
+ * @see Decorator
+ * @see GraphicDecoration
+ * @see StyleClassDecoration
+ */
+public abstract class Decoration {
+    
+    private volatile Map<String,Object> properties;
+    
+    /**
+     * Instantiates a default Decoration instance (obviously only callable by
+     * subclasses).
+     */
+    protected Decoration() {
+        // no-op
+    }
+    
+	/**
+     * This method decorates the given 
+     * target node with the relevant decorations, returning any 'decoration node' 
+     * that needs to be added to the scenegraph (although this can be null). When
+     * the returned Node is null, this indicates that the decoration will be 
+     * handled internally by the decoration (which is preferred, as the default
+     * implementation is not ideal in most circumstances).
+     * 
+     * <p>When the boolean parameter is false, this method removes the decoration 
+     * from the given target node, always returning null.
+     * 
+     * @param targetNode The node to decorate.
+     * @return The decoration, but null is a valid return value.
+     */
+    public abstract Node applyDecoration(Node targetNode);
+    
+    /**
+     * This method removes the decoration from the given target node.
+     * 
+     * @param targetNode The node to undecorate.
+     */
+    public abstract void removeDecoration(Node targetNode);
+    
+    /**
+     * Custom decoration properties
+     * @return decoration properties
+     */
+    public synchronized final Map<String,Object> getProperties() {
+        if (properties == null) {
+            properties = new HashMap<>();
+        }
+    	return properties;
+    }
+}
diff --git a/src/org/controlsfx/control/decoration/Decorator.java b/src/org/controlsfx/control/decoration/Decorator.java
new file mode 100644
index 0000000000000000000000000000000000000000..07435938ce43aeb55542a0752b4f507bb0b4ad91
--- /dev/null
+++ b/src/org/controlsfx/control/decoration/Decorator.java
@@ -0,0 +1,241 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.decoration;
+
+import impl.org.controlsfx.ImplUtils;
+import impl.org.controlsfx.skin.DecorationPane;
+
+import java.util.*;
+import java.util.function.Consumer;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.TextField;
+
+/**
+ * The Decorator class is responsible for accessing decorations for a given node.
+ * Through this class you may therefore add and remove decorations as desired.
+ * 
+ * <h3>Code Example</h3>
+ * <p>Say you have a {@link TextField} that you want to decorate. You would simply
+ * do the following:
+ * 
+ * <pre>
+ * {@code 
+ * TextField textfield = new TextField();
+ * Node decoration = ... // could be an ImageView or any Node!
+ * Decorator.addDecoration(textfield, new GraphicDecoration(decoration, Pos.CENTER_RIGHT));}
+ * </pre>
+ * 
+ * <p>Similarly, if we wanted to add a CSS style class (e.g. because we have some 
+ * css that knows to make the 'warning' style class turn the TextField a lovely
+ * shade of bright red, we would simply do the following:
+ * 
+ * <pre>
+ * {@code 
+ * TextField textfield = new TextField();
+ * Decorator.addDecoration(textfield, new StyleClassDecoration("warning");}
+ * </pre>
+ * 
+ * @see Decoration
+ */
+public class Decorator {
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Static fields                                                           *
+     *                                                                         *
+     **************************************************************************/
+
+    private final static String DECORATIONS_PROPERTY_KEY = "$org.controlsfx.decorations$"; //$NON-NLS-1$
+
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+    
+    private Decorator() {
+        // no op
+    }
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Static API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Adds the given decoration to the given node.
+     * @param target The node to add the decoration to.
+     * @param decoration The decoration to add to the node.
+     */
+    public static final void addDecoration(Node target, Decoration decoration) {
+        getDecorations(target, true).add(decoration);
+        updateDecorationsOnNode(target, FXCollections.observableArrayList(decoration), null);
+    }
+
+    /**
+     * Removes the given decoration from the given node.
+     * @param target The node to remove the decoration from.
+     * @param decoration The decoration to remove from the node.
+     */
+    public static final void removeDecoration(Node target, Decoration decoration) {
+        getDecorations(target, true).remove(decoration);
+        updateDecorationsOnNode(target, null, FXCollections.observableArrayList(decoration));
+    }
+    
+    /**
+     * Removes all the decorations that have previously been set on the given node.
+     * @param target The node from which all previously set decorations should be removed.
+     */
+    public static final void removeAllDecorations(Node target) {
+        List<Decoration> decorations = getDecorations(target, true);
+        List<Decoration> removed = FXCollections.observableArrayList(decorations);
+        
+        target.getProperties().remove(DECORATIONS_PROPERTY_KEY);
+        
+        updateDecorationsOnNode(target, null, removed);
+    }
+    
+    /**
+     * Returns all the currently set decorations for the given node.
+     * @param target The node for which all currently set decorations are required.
+     * @return An ObservableList of the currently set decorations for the given node.
+     */
+    public static final ObservableList<Decoration> getDecorations(Node target) {
+        return getDecorations(target, false);
+    }
+
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Implementation                                                          *
+     *                                                                         *
+     **************************************************************************/
+    
+    private static final ObservableList<Decoration> getDecorations(Node target, boolean createIfAbsent) {
+        @SuppressWarnings("unchecked")
+        ObservableList<Decoration> decorations = (ObservableList<Decoration>) target.getProperties().get(DECORATIONS_PROPERTY_KEY);
+        if (decorations == null && createIfAbsent) {
+            decorations = FXCollections.observableArrayList();
+            target.getProperties().put(DECORATIONS_PROPERTY_KEY, decorations);
+        }
+        return decorations;
+    }
+    
+    private static void updateDecorationsOnNode(Node target, List<Decoration> added, List<Decoration> removed) {
+        // find a DecorationPane parent and notify it that a node has updated
+        // decorations
+        getDecorationPane(target, (pane) -> pane.updateDecorationsOnNode(target, added, removed));
+    }
+    
+    private static List<Scene> currentlyInstallingScenes = new ArrayList<>();
+    private static Map<Scene, List<Consumer<DecorationPane>>> pendingTasksByScene = new HashMap<>();
+    
+    private static void getDecorationPane(Node target, Consumer<DecorationPane> task) {
+        // find a DecorationPane parent and notify it that a node has updated
+        // decorations. If a DecorationPane doesn't exist, we install it into
+        // the scene. If a Scene does not exist, we add a listener to try again
+        // when a scene is available.
+        
+        DecorationPane pane = getDecorationPaneInParentHierarchy(target);
+        
+        if (pane != null) {
+            task.accept(pane);
+        } else {
+            // install decoration pane
+            final Consumer<Scene> sceneConsumer = scene -> {
+                if (currentlyInstallingScenes.contains(scene)) {
+                    List<Consumer<DecorationPane>> pendingTasks = pendingTasksByScene.get(scene);
+                    if (pendingTasks == null) {
+                        pendingTasks = new LinkedList<>();
+                        pendingTasksByScene.put(scene, pendingTasks);
+                    }
+                    pendingTasks.add(task);
+                    return;
+                }
+                
+                DecorationPane _pane = getDecorationPaneInParentHierarchy(target);
+                if (_pane == null) {
+                    currentlyInstallingScenes.add(scene);
+                    _pane = new DecorationPane();
+                    Node oldRoot = scene.getRoot();
+                    ImplUtils.injectAsRootPane(scene, _pane, true);
+                    _pane.setRoot(oldRoot);
+                    currentlyInstallingScenes.remove(scene);
+                }
+                
+                task.accept(_pane);
+                final List<Consumer<DecorationPane>> pendingTasks = pendingTasksByScene.remove(scene);
+                if (pendingTasks != null) {
+                    for (Consumer<DecorationPane> pendingTask : pendingTasks) {
+                        pendingTask.accept(_pane);
+                    }
+                }
+            };
+            
+            Scene scene = target.getScene();
+            if (scene != null) {
+                sceneConsumer.accept(scene);
+            } else {
+                // install listener to try again later
+                InvalidationListener sceneListener = new InvalidationListener() {
+                    @Override public void invalidated(Observable o) {
+                        if (target.getScene() != null) {
+                            target.sceneProperty().removeListener(this);
+                            sceneConsumer.accept(target.getScene());
+                        }
+                    }
+                };
+                target.sceneProperty().addListener(sceneListener);
+            }
+        }
+    }
+    
+    private static DecorationPane getDecorationPaneInParentHierarchy(Node target) {
+        Parent p = target.getParent();
+        while (p != null) {
+            if (p instanceof DecorationPane) {
+                return (DecorationPane) p;
+            }
+            p = p.getParent();
+        }
+        return null;
+    }
+}
diff --git a/src/org/controlsfx/control/decoration/GraphicDecoration.java b/src/org/controlsfx/control/decoration/GraphicDecoration.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca521adc4d5bce3204286e6ab88b3a52235f2f9d
--- /dev/null
+++ b/src/org/controlsfx/control/decoration/GraphicDecoration.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.decoration;
+
+import impl.org.controlsfx.ImplUtils;
+
+import java.util.List;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
+import javafx.geometry.Bounds;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.image.ImageView;
+
+/**
+ * GraphicDecoration is a {@link Decoration} designed to show a graphic (be it
+ * an image loaded via an {@link ImageView} or an arbitrarily complex 
+ * scenegraph in its own right) on top of a given node. GraphicDecoration is
+ * applied as part of the ControlsFX {@link Decorator} API - refer to the 
+ * {@link Decorator} javadoc for more details.
+ * 
+ * @see Decoration
+ * @see Decorator
+ */
+public class GraphicDecoration extends Decoration {
+
+    private final Node decorationNode;
+    private final Pos pos;
+    private final double xOffset;
+    private final double yOffset;
+
+    /**
+     * Constructs a new GraphicDecoration with the given decoration node to be 
+     * applied to any node that has this decoration applied to it. By default
+     * the decoration node will be applied in the top-left corner of the node.
+     * 
+     * @param decorationNode The decoration node to apply to any node that has this 
+     *      decoration applied to it 
+     */
+    public GraphicDecoration(Node decorationNode) {
+        this(decorationNode, Pos.TOP_LEFT);
+    }
+    
+    /**
+     * Constructs a new GraphicDecoration with the given decoration node to be 
+     * applied to any node that has this decoration applied to it, in the location
+     * provided by the {@link Pos position} argument.
+     * 
+     * @param decorationNode The decoration node to apply to any node that has this 
+     *      decoration applied to it 
+     * @param position The location to position the decoration node relative to the 
+     *      node that is being decorated.
+     */
+    public GraphicDecoration(Node decorationNode, Pos position) {
+        this(decorationNode, position, 0, 0);
+    }
+    
+    /**
+     * Constructs a new GraphicDecoration with the given decoration node to be 
+     * applied to any node that has this decoration applied to it, in the location
+     * provided by the {@link Pos position} argument, with the given xOffset and
+     * yOffset values used to adjust the position.
+     * 
+     * @param decorationNode The decoration node to apply to any node that has this 
+     *      decoration applied to it 
+     * @param position The location to position the decoration node relative to the 
+     *      node that is being decorated.
+     * @param xOffset The amount of movement to apply to the decoration node in the
+     *      x direction (i.e. left and right).
+     * @param yOffset The amount of movement to apply to the decoration node in the
+     *      y direction (i.e. up and down). 
+     */
+    public GraphicDecoration(Node decorationNode, Pos position, double xOffset, double yOffset) {
+        this.decorationNode = decorationNode;
+        this.decorationNode.setManaged(false);
+        this.pos = position;
+        this.xOffset = xOffset;
+        this.yOffset = yOffset;
+    }
+    
+    /** {@inheritDoc} */
+    @Override public Node applyDecoration(Node targetNode) {
+        List<Node> targetNodeChildren = ImplUtils.getChildren((Parent)targetNode, true);
+        updateGraphicPosition(targetNode);
+        if (!targetNodeChildren.contains(decorationNode)) {
+            targetNodeChildren.add(decorationNode);
+        }
+        return null;
+    }
+    
+    /** {@inheritDoc} */
+    @Override public void removeDecoration(Node targetNode) {
+        List<Node> targetNodeChildren = ImplUtils.getChildren((Parent)targetNode, true);
+        
+        if (targetNodeChildren.contains(decorationNode)) {
+            targetNodeChildren.remove(decorationNode);
+        }
+    }
+    
+    private void updateGraphicPosition(Node targetNode) {
+        final double decorationNodeWidth = decorationNode.prefWidth(-1);
+        final double decorationNodeHeight = decorationNode.prefHeight(-1);
+        
+        Bounds targetBounds = targetNode.getLayoutBounds();
+        double x = targetBounds.getMinX();
+        double y = targetBounds.getMinY();
+
+        double targetWidth = targetBounds.getWidth();
+        if (targetWidth <= 0) {
+            targetWidth = targetNode.prefWidth(-1);
+        }
+        
+        double targetHeight = targetBounds.getHeight();
+        if (targetHeight <= 0) {
+            targetHeight = targetNode.prefHeight(-1);
+        }
+
+        /**
+         * If both targetWidth and targetHeight are equal to 0, this means the
+         * targetNode has not been laid out so we can put a listener in order to
+         * catch when the layout will be updated, and then we will place our
+         * decorationNode to the proper position.
+         */
+        if (targetWidth <= 0 && targetHeight <= 0) {
+            targetNode.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
+
+                @Override
+                public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) {
+                    targetNode.layoutBoundsProperty().removeListener(this);
+                    updateGraphicPosition(targetNode);
+                }
+            });
+        }
+        
+        // x
+        switch (pos.getHpos()) {
+        	case CENTER: 
+        		x += targetWidth/2 - decorationNodeWidth / 2.0;
+        		break;
+        	case LEFT: 
+        		x -= decorationNodeWidth / 2.0;
+        		break;
+        	case RIGHT:
+        		x += targetWidth - decorationNodeWidth / 2.0;
+        		break;
+        }
+        
+        // y
+        switch (pos.getVpos()) {
+        	case CENTER: 
+        		y += targetHeight/2 - decorationNodeHeight / 2.0;
+        		break;
+        	case TOP: 
+        		y -= decorationNodeHeight / 2.0;
+        		break;
+        	case BOTTOM:
+        		y += targetHeight - decorationNodeWidth / 2.0;
+        		break;
+        	case BASELINE: 
+        		y += targetNode.getBaselineOffset() - decorationNode.getBaselineOffset() - decorationNodeHeight / 2.0;
+        		break;
+        }
+        
+        decorationNode.setLayoutX(x + xOffset);
+        decorationNode.setLayoutY(y + yOffset);
+    }
+}
diff --git a/src/org/controlsfx/control/decoration/StyleClassDecoration.java b/src/org/controlsfx/control/decoration/StyleClassDecoration.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e86b8b4659309028caa74ae57e3cd34d63b7d38
--- /dev/null
+++ b/src/org/controlsfx/control/decoration/StyleClassDecoration.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.decoration;
+
+import java.util.List;
+
+import javafx.scene.Node;
+
+/**
+ * StyleClassDecoration is a {@link Decoration} designed to add a CSS style class
+ * to a node (for example, to show a warning style when the field is incorrectly 
+ * set). StyleClassDecoration is applied as part of the ControlsFX {@link Decorator} 
+ * API - refer to the {@link Decorator} javadoc for more details.
+ * 
+ * @see Decoration
+ * @see Decorator
+ */
+public class StyleClassDecoration extends Decoration {
+
+    private final String[] styleClasses;
+
+    /**
+     * Constructs a new StyleClassDecoration with the given var-args array of 
+     * style classes set to be applied to any node that has this decoration 
+     * applied to it.
+     * 
+     * @param styleClass A var-args array of style classes to apply to any node.
+     * @throws IllegalArgumentException if the styleClass varargs array is null or empty.
+     */
+    public StyleClassDecoration(String... styleClass) {
+        if (styleClass == null || styleClass.length == 0) {
+            throw new IllegalArgumentException("var-arg style class array must not be null or empty"); //$NON-NLS-1$
+        }
+        this.styleClasses = styleClass;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Node applyDecoration(Node targetNode) {
+        final List<String> styleClassList = targetNode.getStyleClass();
+        
+        for (String styleClass : styleClasses) {
+            if (styleClassList.contains(styleClass)) {
+                continue;
+            }
+    
+            styleClassList.add(styleClass);
+        }
+            
+        // no decoration node, so return null
+        return null;
+    }
+    
+    /** {@inheritDoc} */
+    @Override public void removeDecoration(Node targetNode) {
+        targetNode.getStyleClass().removeAll(styleClasses);
+    }
+}
diff --git a/src/org/controlsfx/control/decoration/package-info.java b/src/org/controlsfx/control/decoration/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..da9c05887d71bc64c50b55bbe0ade63785097215
--- /dev/null
+++ b/src/org/controlsfx/control/decoration/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * A package containing decoration-related API (that is, API to allow for users
+ * to 'decorate' nodes with additional nodes or css decorations.
+ */
+package org.controlsfx.control.decoration;
\ No newline at end of file
diff --git a/src/org/controlsfx/control/expand.png b/src/org/controlsfx/control/expand.png
new file mode 100644
index 0000000000000000000000000000000000000000..c45d4ac09eaa74b5ab9894fa5eef2f28e9c46376
Binary files /dev/null and b/src/org/controlsfx/control/expand.png differ
diff --git a/src/org/controlsfx/control/format-indent-more.png b/src/org/controlsfx/control/format-indent-more.png
new file mode 100644
index 0000000000000000000000000000000000000000..d57376f6bbfd8bda976f998f1436a5bf2a801578
Binary files /dev/null and b/src/org/controlsfx/control/format-indent-more.png differ
diff --git a/src/org/controlsfx/control/format-line-spacing-triple.png b/src/org/controlsfx/control/format-line-spacing-triple.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e80972978fabf98774a16acc6856b65137114c0
Binary files /dev/null and b/src/org/controlsfx/control/format-line-spacing-triple.png differ
diff --git a/src/org/controlsfx/control/gridview.css b/src/org/controlsfx/control/gridview.css
new file mode 100644
index 0000000000000000000000000000000000000000..ea2c3ca12072d09e02e1fae58e2b1025150c2952
--- /dev/null
+++ b/src/org/controlsfx/control/gridview.css
@@ -0,0 +1,7 @@
+.grid-view {
+	-fx-vertical-cell-spacing: 12;
+	-fx-horizontal-cell-spacing: 12;
+	-fx-cell-height: 64;
+	-fx-cell-width: 64;
+	-fx-horizontal-alignment: CENTER;
+}
diff --git a/src/org/controlsfx/control/info-overlay.css b/src/org/controlsfx/control/info-overlay.css
new file mode 100644
index 0000000000000000000000000000000000000000..a18ded78e0c7eed831803f6757906ece954bcf89
--- /dev/null
+++ b/src/org/controlsfx/control/info-overlay.css
@@ -0,0 +1,15 @@
+.info-overlay > .info-panel {
+    -fx-background-color: lightgray;
+    -fx-opacity: .75;
+    -fx-padding: 5 5 5 5;
+}
+
+.info-panel > .info-panel > .expand-button {
+    -fx-padding: 0 0 0 0 ;
+    /*-fx-graphic: url("/helloworld/david/collapse.png");*/
+}
+
+.info-panel > .info-panel > .collapse-button {
+    -fx-padding: 0 0 0 0 ;
+    /*-fx-graphic: url("expand.png");*/
+}
diff --git a/src/org/controlsfx/control/listselectionview.css b/src/org/controlsfx/control/listselectionview.css
new file mode 100644
index 0000000000000000000000000000000000000000..c13cd77f2ffb09c8a1da6c22d85cdadc7526c702
--- /dev/null
+++ b/src/org/controlsfx/control/listselectionview.css
@@ -0,0 +1,13 @@
+.list-selection-view {
+	-fx-padding: 10px;	
+}
+
+.list-selection-view > .grid-pane {
+	-fx-vgap: 10px;
+	-fx-hgap: 10px;
+}
+
+.list-selection-view > .grid-pane > .list-header-label {
+	-fx-font-size: 1.0em;
+	-fx-font-weight: bold;
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/maskerpane.css b/src/org/controlsfx/control/maskerpane.css
new file mode 100644
index 0000000000000000000000000000000000000000..cf0c78da9b8ad89046aa7e2dba6145d90550fc20
--- /dev/null
+++ b/src/org/controlsfx/control/maskerpane.css
@@ -0,0 +1,17 @@
+.masker-pane {}
+
+.masker-pane .masker-glass {
+    -fx-background-color: rgba(0, 0, 0, .3);
+}
+
+.masker-pane .masker-text {
+    -fx-text-fill: white;
+    -fx-font-weight: bold;
+}
+
+.masker-pane .masker-center {
+    -fx-background-color: rgba(0, 0, 0, .6);
+    -fx-max-height: 1.50in;
+    -fx-padding: .25in;
+    -fx-background-radius: .1in;
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/masterdetailpane.css b/src/org/controlsfx/control/masterdetailpane.css
new file mode 100644
index 0000000000000000000000000000000000000000..82d11f1998525f6072d119a1fceea3906dd683ca
--- /dev/null
+++ b/src/org/controlsfx/control/masterdetailpane.css
@@ -0,0 +1,14 @@
+.tab-pane > * > .master-detail-pane > .split-pane,
+.split-pane > * > .master-detail-pane > .split-pane {
+    -fx-background-insets: 0, 0;
+    -fx-padding: 0;
+ }
+.tab-pane.floating > * > .master-detail-pane > .split-pane {
+    -fx-background-insets: 0, 0;
+    -fx-padding: -1;
+}
+.titled-pane > * > * > .master-detail-pane > .split-pane {
+    -fx-background-color: null;
+    -fx-background-insets: 0, 0;
+    -fx-padding: 0;
+}
diff --git a/src/org/controlsfx/control/notificationpane.css b/src/org/controlsfx/control/notificationpane.css
new file mode 100644
index 0000000000000000000000000000000000000000..765ec1b7614eaec42311a8afea1cb5e9092ec328
--- /dev/null
+++ b/src/org/controlsfx/control/notificationpane.css
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * 
+ * Light theme
+ * 
+ *****************************************************************************/
+
+.notification-pane .notification-bar > .pane {
+    -fx-background-color: -fx-outer-border, -fx-inner-border, -fx-body-color;
+    -fx-padding: 0 7 0 7;
+}
+
+.notification-pane.top .notification-bar > .pane {
+    -fx-background-insets: 0 0 0 0, 0 0 1 0, 0 0 2 0;
+}
+
+.notification-pane.bottom .notification-bar > .pane {
+    -fx-background-insets: 0 0 0 0, 1 0 0 0, 2 0 0 0;
+}
+
+.notification-pane .notification-bar > .pane .label {
+    -fx-font-size: 1.166667em; /*15px;*/
+    -fx-text-fill: #292929;
+}
+
+
+/******************************************************************************
+ * 
+ * Dark theme
+ * 
+ *****************************************************************************/
+
+.notification-pane.dark .notification-bar > .pane {
+    -fx-background-color: linear-gradient(#595959, #474747 37%, #343434);
+}
+
+.notification-pane.dark .notification-bar > .pane .label {
+    -fx-text-fill: #ebebeb;
+}
+
+
+/******************************************************************************
+ * 
+ * Drop shadow support
+ * 
+ *****************************************************************************/
+
+/* NotificationPane shows from the top, so put shadow at bottom of bar */
+.notification-pane.top .notification-bar > .pane {
+    -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.4), 11, 0.0, 0, 3);
+}
+
+/* 
+ * We could have a drop shadow at the top of the bar when it appears from the
+ * bottom, but it doesn't look right as the gradient is running in the opposite
+ * direction of the drop shadow. Therefore, the following is commented out,
+ * but it can always be re-enabled in the future if desired.
+ */
+ /*
+.notification-pane:bottom .notification-bar > .pane {
+    -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.4), 11, 0.0, 0, -3);
+}
+*/
+
+
+
+/******************************************************************************
+ * 
+ * Close button
+ * 
+ *****************************************************************************/
+.notification-pane .notification-bar > .pane .close-button {
+    -fx-background-color: transparent;
+    -fx-background-insets: 0;
+    -fx-background-radius: 2;
+    -fx-padding: 0 0 0 0;
+    -fx-alignment: center;
+}
+
+.notification-pane .notification-bar > .pane .close-button:hover {
+    -fx-background-color: linear-gradient(#a3a3a3, #8b8b8b 34%, #777777 36%, #777777 63%, #8b8b8b 65%, #adadad);
+}
+
+.notification-pane .notification-bar > .pane .close-button:pressed {
+    -fx-background-color: linear-gradient(#a3a3a3, #8b8b8b 34%, #777777 36%, #777777 63%, #8b8b8b 65%, #adadad);
+}
+
+.notification-pane .notification-bar > .pane .close-button > .graphic {
+    -fx-background-color: #949494;
+    -fx-scale-shape: false;
+    -fx-padding: 4.5 4.5 4.5 4.5; /* Graphic is 9x9 px */
+}
+
+.notification-pane .notification-bar > .pane .close-button:hover > .graphic {
+    -fx-background-color: #fefeff;
+}
+
+.notification-pane .notification-bar > .pane .close-button:pressed > .graphic {
+    -fx-background-color: #cfcfcf;
+}
+
+.notification-pane .notification-bar > .pane .close-button > .graphic {
+    -fx-shape: "M395.992,296.758l1.794-1.794l7.292,7.292l-1.795,1.794 L395.992,296.758z M403.256,294.992l1.794,1.794l-7.292,7.292l-1.794-1.795 L403.256,294.992z";
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/notificationpopup.css b/src/org/controlsfx/control/notificationpopup.css
new file mode 100644
index 0000000000000000000000000000000000000000..a35fa1575d11122e7fc8ff11bd8a9f524efb727e
--- /dev/null
+++ b/src/org/controlsfx/control/notificationpopup.css
@@ -0,0 +1,79 @@
+/******************************************************************************
+ * 
+ * Light theme
+ * 
+ *****************************************************************************/
+
+.notification-bar > .pane {
+    -fx-background-color: -fx-outer-border, -fx-inner-border, -fx-body-color;
+    -fx-padding: 7 7 7 7;
+    -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.4), 11, 0.0, 0, 3);
+    -fx-background-insets: 0, 1, 2;
+}
+
+.notification-bar > .pane .title {
+    -fx-font-size: 1.166667em; /*15px;*/
+    -fx-text-fill: #292929;
+    -fx-font-weight: bold;
+}
+
+.notification-bar > .pane .label {
+    -fx-font-size: 1.166667em; /*15px;*/
+    -fx-text-fill: #292929;
+    -fx-alignment: top-left;
+}
+
+/******************************************************************************
+ * 
+ * Dark theme
+ * 
+ *****************************************************************************/
+
+.notification-bar.dark > .pane {
+    -fx-background-color: -fx-outer-border, -fx-inner-border, linear-gradient(#595959, #474747 37%, #343434);
+}
+
+.notification-bar.dark > .pane .title,
+.notification-bar.dark > .pane .label {
+    -fx-text-fill: #ebebeb;
+}
+
+
+/******************************************************************************
+ * 
+ * Close button
+ * 
+ *****************************************************************************/
+ .notification-bar > .pane .close-button {
+    -fx-background-color: transparent;
+    -fx-background-insets: 0;
+    -fx-background-radius: 2;
+    -fx-padding: 0 0 0 0;
+    -fx-alignment: center;
+}
+
+.notification-bar > .pane .close-button:hover {
+    -fx-background-color: linear-gradient(#a3a3a3, #8b8b8b 34%, #777777 36%, #777777 63%, #8b8b8b 65%, #adadad);
+}
+
+.notification-bar > .pane .close-button:pressed {
+    -fx-background-color: linear-gradient(#a3a3a3, #8b8b8b 34%, #777777 36%, #777777 63%, #8b8b8b 65%, #adadad);
+}
+
+.notification-bar > .pane .close-button > .graphic {
+    -fx-background-color: #949494;
+    -fx-scale-shape: false;
+    -fx-padding: 4.5 4.5 4.5 4.5; /* Graphic is 9x9 px */
+}
+
+.notification-bar > .pane .close-button:hover > .graphic {
+    -fx-background-color: #fefeff;
+}
+
+.notification-bar > .pane .close-button:pressed > .graphic {
+    -fx-background-color: #cfcfcf;
+}
+
+.notification-bar > .pane .close-button > .graphic {
+    -fx-shape: "M395.992,296.758l1.794-1.794l7.292,7.292l-1.795,1.794 L395.992,296.758z M403.256,294.992l1.794,1.794l-7.292,7.292l-1.794-1.795 L403.256,294.992z";
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/open-editor.png b/src/org/controlsfx/control/open-editor.png
new file mode 100644
index 0000000000000000000000000000000000000000..87d22c3c98b41d3264f0b8fc48f72517e2b184ec
Binary files /dev/null and b/src/org/controlsfx/control/open-editor.png differ
diff --git a/src/org/controlsfx/control/package-info.java b/src/org/controlsfx/control/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..f22fac2bba00a6bb314da253454f0aa51e5473c6
--- /dev/null
+++ b/src/org/controlsfx/control/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * A package containing a number of useful controls-related classes that do not
+ * exist in the base JavaFX distribution.
+ */
+package org.controlsfx.control;
\ No newline at end of file
diff --git a/src/org/controlsfx/control/plusminusslider.css b/src/org/controlsfx/control/plusminusslider.css
new file mode 100644
index 0000000000000000000000000000000000000000..86cb6f1b74c9d71aa65216b864add559ce84fed8
--- /dev/null
+++ b/src/org/controlsfx/control/plusminusslider.css
@@ -0,0 +1,57 @@
+.plus-minus-slider {
+    -fx-background-radius: 2.0;
+    -fx-border-color: -fx-box-border;
+    -fx-border-radius: 2.0;
+}
+
+.plus-minus-slider:horizontal {
+    -fx-background-color: derive(-fx-box-border,30.0%), linear-gradient(to bottom, derive(-fx-base,-3.0%), derive(-fx-base,5.0%) 50.0%, derive(-fx-base,-3.0%));
+    -fx-background-insets: 0.0, 1.0 0.0 1.0 0.0;
+    -fx-pref-height: 16.0;
+    -fx-max-height: 16.0;
+}
+
+.plus-minus-slider:vertical {
+    -fx-background-color: derive(-fx-box-border,30.0%), linear-gradient(to right, derive(-fx-base,-3.0%), derive(-fx-base,5.0%) 50.0%, derive(-fx-base,-3.0%));
+    -fx-background-insets: 0.0, 0.0 1.0 0.0 1.0;
+    -fx-pref-width: 16.0;
+    -fx-max-width: 16.0;
+}
+
+.plus-minus-slider > * > .slider {
+    -fx-show-tick-marks: false;
+}
+
+.plus-minus-slider > * > .slider > .track {
+    -fx-background-color: transparent;
+}
+
+.plus-minus-slider > * > .slider > .thumb {
+    -fx-background-color: -fx-outer-border, -fx-inner-border, -fx-body-color; 
+    -fx-background-insets: 2.0, 3.0, 4.0;
+    -fx-background-radius: 3.0, 2.0, 1.0;
+}
+
+.plus-minus-slider > * > .slider:focused > .thumb {
+    -fx-background-color: -fx-focus-color, -fx-inner-border, -fx-body-color, -fx-faint-focus-color, -fx-body-color;
+    -fx-background-insets: 1.8, 3.0, 4.0, 0.6, 4.6;
+    -fx-background-radius: 3.0, 2.0, 1.0, 4.0, 1.0;
+}
+
+.plus-minus-slider > * > .adjust-plus {
+    -fx-pref-width: 16.0;
+    -fx-pref-height: 16.0;
+    -fx-shape: "M0,3 H3 V0 H5 V3 H8 V5 H5 V8 H3 V5 H0 V3 Z";
+    -fx-scale-shape: false;
+    -fx-effect: dropshadow(two-pass-box , -fx-shadow-highlight-color, 1.0, 0.0 , 0.0, 1.4);
+    -fx-background-color: -fx-mark-highlight-color,derive(-fx-base,-45.0%);
+}
+
+.plus-minus-slider > * > .adjust-minus {
+    -fx-pref-width: 16.0;
+    -fx-pref-height: 16.0;
+    -fx-shape: "M0,0H8V2H0Z";
+    -fx-scale-shape: false;
+    -fx-effect: dropshadow(two-pass-box , -fx-shadow-highlight-color, 1.0, 0.0 , 0.0, 1.4);
+    -fx-background-color: -fx-mark-highlight-color,derive(-fx-base,-45.0%);
+}
diff --git a/src/org/controlsfx/control/popover.css b/src/org/controlsfx/control/popover.css
new file mode 100644
index 0000000000000000000000000000000000000000..c9dd527cd66d336340e15e5c9b1b6defc44c0caa
--- /dev/null
+++ b/src/org/controlsfx/control/popover.css
@@ -0,0 +1,36 @@
+.popover  {
+	-fx-background-color: transparent;
+}
+
+.popover > .border {
+	-fx-stroke: linear-gradient(to bottom, rgba(0,0,0, .3), rgba(0, 0, 0, .7)) ;
+	-fx-stroke-width: 0.5;
+	-fx-fill: rgba(255.0,255.0,255.0, .95);
+	-fx-effect: dropshadow(gaussian, rgba(0,0,0,.2), 10.0, 0.5, 2.0, 2.0);
+}
+
+.popover > .content {
+}
+
+.popover > .detached {
+}
+
+.popover > .content > .title > .text  {
+	-fx-padding: 6.0 6.0 0.0 6.0;
+	-fx-text-fill: rgba(120, 120, 120, .8);
+	-fx-font-weight: bold;
+}
+
+.popover > .content > .title > .icon {
+	-fx-padding: 6.0 0.0 0.0 10.0;
+}
+
+.popover > .content > .title > .icon > .graphics > .circle {
+	-fx-fill: gray ;
+	-fx-effect: innershadow(gaussian, rgba(0,0,0,.2), 3, 0.5, 1.0, 1.0);
+}
+
+.popover > .content > .title > .icon > .graphics > .line {
+	-fx-stroke: white ;
+	-fx-stroke-width: 2;
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/propertysheet.css b/src/org/controlsfx/control/propertysheet.css
new file mode 100644
index 0000000000000000000000000000000000000000..3846aca5d56cdae5954330a984d485e331a6aa81
--- /dev/null
+++ b/src/org/controlsfx/control/propertysheet.css
@@ -0,0 +1,15 @@
+/* Remove extraneous borders from PropertySheet */
+
+.property-sheet .scroll-pane .property-pane {
+    -fx-background-color: -fx-background;
+}
+
+.property-sheet .scroll-pane {
+    -fx-background-color: -fx-background;
+    -fx-background-insets: 0;
+    -fx-padding: 0;
+}
+
+.property-sheet .scroll-pane .accordion {
+    -fx-padding: -1;
+}
diff --git a/src/org/controlsfx/control/rangeslider.css b/src/org/controlsfx/control/rangeslider.css
new file mode 100644
index 0000000000000000000000000000000000000000..373e9d5c3fa095845318b6399ed3ff3521828521
--- /dev/null
+++ b/src/org/controlsfx/control/rangeslider.css
@@ -0,0 +1,86 @@
+
+/*******************************************************************************
+ *                                                                             *
+ * RangeSlider                                                                 *
+ * (Largely derived from Modena styles)                                        *
+ *                                                                             *
+ ******************************************************************************/
+
+.range-slider .low-thumb, 
+.range-slider .high-thumb {
+    -fx-background-color: 
+        linear-gradient(to bottom, derive(-fx-text-box-border, -20%), derive(-fx-text-box-border, -30%)),
+        -fx-inner-border,
+        -fx-body-color;
+    -fx-background-insets: 0, 1, 2;
+    -fx-background-radius: 1.0em; /* makes sure this remains circular */
+    -fx-padding: 0.583333em;  /* 7 */
+    -fx-effect: dropshadow(two-pass-box , rgba(0, 0, 0, 0.1), 5, 0.0 , 0, 2);
+}
+
+.range-slider:focused .low-thumb,
+.range-slider:focused .high-thumb {
+    -fx-background-radius: 1.0em; /* makes sure this remains circular */
+}
+
+.range-slider .low-thumb:focused, 
+.range-slider .high-thumb:focused {
+    -fx-background-color:
+        -fx-focus-color,
+        derive(-fx-color,-36%),
+        derive(-fx-color,73%),
+        linear-gradient(to bottom, derive(-fx-color,-19%),derive(-fx-color,61%));
+    -fx-background-insets: -1.4, 0, 1, 2;
+    -fx-background-radius: 1.0em; /* makes sure this remains circular */
+}
+
+.range-slider .low-thumb:hover, 
+.range-slider .high-thumb:hover {
+    -fx-color: -fx-hover-base;
+}
+
+.range-slider .range-bar {
+    -fx-background-color: -fx-focus-color;
+}
+
+.range-slider .low-thumb:pressed,
+.range-slider .high-thumb:pressed {
+    -fx-color: -fx-pressed-base;
+}
+
+.range-slider .track {
+    -fx-background-color: 
+          -fx-shadow-highlight-color,
+          linear-gradient(to bottom, derive(-fx-text-box-border, -10%), -fx-text-box-border),
+          linear-gradient(to bottom, 
+            derive(-fx-control-inner-background, -9%),
+            derive(-fx-control-inner-background, 0%),
+            derive(-fx-control-inner-background, -5%),
+            derive(-fx-control-inner-background, -12%)
+          );
+    -fx-background-insets: 0 0 -1 0, 0, 1;
+    -fx-background-radius: 0.25em, 0.25em, 0.166667em; /* 3 3 2 */
+    -fx-padding: 0.25em; /* 3 */
+}
+
+.range-slider:vertical .track {
+    -fx-background-color: 
+          -fx-shadow-highlight-color,
+          -fx-text-box-border,
+          linear-gradient(to right, 
+            derive(-fx-control-inner-background, -9%),
+            -fx-control-inner-background,
+            derive(-fx-control-inner-background, -9%)
+          );
+}
+
+.range-slider .axis {
+    -fx-tick-label-fill: derive(-fx-text-background-color, 30%);
+    -fx-tick-length: 5px;
+    -fx-minor-tick-length: 3px;
+    -fx-border-color: null;
+}
+
+.range-slider:disabled {
+    -fx-opacity: 0.4;
+}
diff --git a/src/org/controlsfx/control/rating.css b/src/org/controlsfx/control/rating.css
new file mode 100644
index 0000000000000000000000000000000000000000..393379dbd33176d75a1abe6dd26de87283760eff
--- /dev/null
+++ b/src/org/controlsfx/control/rating.css
@@ -0,0 +1,15 @@
+.rating > .container {
+    -fx-spacing: 4;
+}
+.rating > .container > .button {
+    -fx-background-color: transparent;
+    -fx-background-image: url("unselected-star.png");
+    -fx-padding: 16 16; 
+    -fx-background-image-repeat: no-repeat;
+}
+.rating > .container > .button.strong {
+    -fx-background-image: url("selected-star.png");
+}
+.rating > .container > .button:hover {
+    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 8, 0.0 , 0 , 0 );
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/segmentedbutton.css b/src/org/controlsfx/control/segmentedbutton.css
new file mode 100644
index 0000000000000000000000000000000000000000..0e90a1dfca673351ecc64ee76842c92186cd6c76
--- /dev/null
+++ b/src/org/controlsfx/control/segmentedbutton.css
@@ -0,0 +1,79 @@
+/* -------- Segmented Button ---------------- */
+.segmented-button.dark .toggle-button {
+    -fx-padding: 3 15 3 15;
+    -fx-border-color: transparent -fx-outer-border transparent transparent;
+}
+
+.segmented-button.dark .toggle-button:focused {
+    -fx-background-color:
+        rgba(23,134,248,0.2),
+        -fx-focus-color,
+        -fx-inner-border,
+        -fx-body-color;
+}
+
+.segmented-button.dark .toggle-button:selected Text {
+    -fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.9) , 2, 0.0 , 0 , 1 );
+}
+
+.segmented-button.dark .toggle-button:selected {
+    -fx-background-color:
+        -fx-shadow-highlight-color,
+        linear-gradient( to bottom, derive(-fx-color,-90%) 0%, derive(-fx-color,-60%) 100% ),        
+        linear-gradient( to bottom, derive(-fx-color,-60%) 0%, derive(-fx-color,-35%) 50%, derive(-fx-color,-30%) 98%, derive(-fx-color,-50%) 100% ),    
+        linear-gradient( to right, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0) 10%, rgba(0,0,0,0) 90%, rgba(0,0,0,0.3) 100% );
+    -fx-background-insets: 0 0 -1 0, 0, 1, 1;
+    /* TODO: -fx-text-fill should be derived */
+    -fx-text-fill: -fx-light-text-color;
+}
+
+/* *************************** LEFT BUTTON ************************** */
+.segmented-button.dark .toggle-button.left-pill {
+    -fx-background-radius: 3 0 0 3;
+    -fx-background-insets: 0 0 -1 0, 0, 1 0 1 1, 2 0 2 2;
+}
+
+.segmented-button.dark .toggle-button.left-pill:focused {
+     -fx-background-insets: -2 0 -2 -2, 0 0 0 0, 1, 2;
+	-fx-border-color: transparent;
+}
+
+.segmented-button.dark .toggle-button.left-pill:selected:focused {
+    -fx-background-insets: 0 0 -1 0, 0, 1 0 1 1, 1 0 1 1;
+	-fx-border-color: transparent;
+}
+
+/* *************************** RIGHT BUTTON ************************** */
+.segmented-button.dark .toggle-button.right-pill {
+    -fx-background-radius: 0 3 3 0;
+    -fx-background-insets: 0 0 -1 0, 0, 1 1 1 0, 2 2 2 0;
+    -fx-border-color: transparent;
+}
+
+.segmented-button.dark .toggle-button.right-pill:focused {
+	-fx-background-insets: -2 -2 -2 0, 0, 1, 2;
+     -fx-border-color: transparent;
+}
+
+.segmented-button.dark .toggle-button.right-pill:selected:focused {
+	-fx-background-insets: -1 -1 -1 -1, 0 0 0 -1, 1 1 1 0, 1 1 1 0;
+    -fx-border-color: transparent;
+}
+
+/* *************************** CENTER BUTTON ************************** */
+.segmented-button.dark .toggle-button.center-pill {
+	-fx-background-radius: 0;
+	-fx-background-insets: 0 0 -1 0, 0, 1 0 1 0, 2 0 2 0;
+    
+}
+
+.segmented-button.dark .toggle-button.center-pill:focused {
+	-fx-background-radius: 0;
+	-fx-background-insets: -2 0 -2 -2, 0 0 0 -1, 1 1 1 0, 2 2 2 1;
+	-fx-border-color: transparent;
+}
+
+.segmented-button.dark .toggle-button.center-pill:selected:focused {
+	-fx-background-insets: -1.4 0 -1.4 -1, 0 0 0 -1, 1 1 1 0, 1 1 1 0;
+	-fx-border-color: transparent;
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/selected-star.png b/src/org/controlsfx/control/selected-star.png
new file mode 100644
index 0000000000000000000000000000000000000000..01b0fc0457913c694471b844d50ed84418790b24
Binary files /dev/null and b/src/org/controlsfx/control/selected-star.png differ
diff --git a/src/org/controlsfx/control/snapshot-view.css b/src/org/controlsfx/control/snapshot-view.css
new file mode 100644
index 0000000000000000000000000000000000000000..1aeaeeeef84f6147eff0b06ea45be24dc22970ad
--- /dev/null
+++ b/src/org/controlsfx/control/snapshot-view.css
@@ -0,0 +1,4 @@
+
+.snapshot-view {
+
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/spreadsheet/Grid.java b/src/org/controlsfx/control/spreadsheet/Grid.java
new file mode 100644
index 0000000000000000000000000000000000000000..53ac9e8ecdef75e57298b07d31ab58b0ee646943
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/Grid.java
@@ -0,0 +1,200 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import java.util.Collection;
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+import javafx.event.EventType;
+import org.controlsfx.control.spreadsheet.SpreadsheetView.SpanType;
+
+/**
+ * That class holds some {@link SpreadsheetCell} in order
+ * to be used by the {@link SpreadsheetView}.
+ * 
+ * A Grid is used by {@link SpreadsheetView} to represent the data to show on
+ * screen. A default implementation is provided by {@link GridBase}, but for 
+ * more custom purposes (e.g. loading data on demand), this Grid interface may
+ * prove useful.
+ * 
+ * <p>A Grid at its essence consists of rows and columns. Critical to the 
+ * SpreadsheetView is that the {@link #getRowCount() row count} and 
+ * {@link #getColumnCount() column count} are accurately returned when requested
+ * (even if the data returned by {@link #getRows()} is not all fully loaded into
+ * memory). 
+ * 
+ * <p>Whilst the {@link #getRows()} return type may appear confusing, it is 
+ * actually quite logical when you think about it: {@link #getRows()} returns an
+ * ObservableList of ObservableList of {@link SpreadsheetCell} instances. In other
+ * words, this is your classic 2D collection, where the outer ObservableList
+ * can be thought of as the rows, and the inner ObservableList as the columns
+ * within each row. Therefore, if you are wanting to iterate through all columns
+ * in every row of the grid, you would do something like this:
+ * 
+ * 
+ * <h3> Code Sample </h3>
+ * <pre>
+ * Grid grid = ...
+ * for (int row = 0; row &lt; grid.getRowCount(); row++) {
+ *     for (int column = 0; column &lt; grid.getColumnCount(); column++) {
+ *         SpreadsheetCell&lt;?&gt; cell = getRows().get(row).get(column);
+ *         doStuff(cell);
+ *     }
+ * }
+ * 
+ * </pre>
+ * 
+ * @see SpreadsheetView
+ * @see GridBase
+ * @see SpreadsheetCell
+ */
+public interface Grid {
+    /**
+     * This value may be returned from {@link #getRowHeight(int) } in order to
+     * let the system compute the best row height.
+     */
+    public static final double AUTOFIT = -1;
+    
+    /**
+     * @return how many rows are inside the grid.
+     */
+    public int getRowCount();
+    
+    /**
+     * @return how many columns are inside the grid.
+     */
+    public int getColumnCount();
+    
+    /**
+     * Return an ObservableList of ObservableList of {@link SpreadsheetCell}
+     * instances. Refer to the {@link Grid} class javadoc for more detail.
+     * @return an ObservableList of ObservableList of {@link SpreadsheetCell}
+     * instances
+     */
+    public ObservableList<ObservableList<SpreadsheetCell>> getRows();
+
+    /**
+     * Change the value situated at the intersection if possible.
+     * Verification and conversion of the value should be done before 
+     * with {@link SpreadsheetCellType#match(Object)}
+     * and {@link SpreadsheetCellType#convertValue(Object)}.
+     * @param row
+     * @param column
+     * @param value
+     */
+    public void setCellValue(int row, int column, Object value);
+    
+    /**
+     * Return the {@link SpanType} for a given cell row/column intersection.
+     * @param spv
+     * @param row
+     * @param column
+     * @return the {@link SpanType} for a given cell row/column intersection.
+     */
+    public SpanType getSpanType(final SpreadsheetView spv, final int row, final int column);
+    
+    /**
+     * Return the height of a row. {@link #AUTOFIT } can be returned in order to
+     * let the system compute the best row height.
+     *
+     * @param row
+     * @return the height of a row.
+     */
+    public double getRowHeight(int row);
+
+    /**
+     * Return true if the specified row is resizable.
+     * @param row
+     * @return true if the specified row is resizable.
+     */
+    public boolean isRowResizable(int row);
+    
+    /**
+     * Returns an ObservableList of string to display in the row headers.
+     * 
+     * @return an ObservableList of string to display in the row headers.
+     */
+    public ObservableList<String> getRowHeaders();
+    
+    /**
+     * Returns an ObservableList of string to display in the column headers.
+     * 
+     * @return an ObservableList of string to display in the column headers.
+     */
+    public ObservableList<String> getColumnHeaders();
+    
+    /**
+     * Span in row the cell situated at rowIndex and colIndex by the number
+     * count
+     * 
+     * @param count
+     * @param rowIndex
+     * @param colIndex
+     */
+    public void spanRow(int count, int rowIndex, int colIndex);
+    
+    /**
+     * Span in column the cell situated at rowIndex and colIndex by the number
+     * count
+     * 
+     * @param count
+     * @param rowIndex
+     * @param colIndex
+     */
+    public void spanColumn(int count, int rowIndex, int colIndex);
+    
+    /**
+     * This method sets the rows used by the grid, and updates the rowCount.
+     * @param rows
+     */
+    public void setRows(Collection<ObservableList<SpreadsheetCell>> rows);
+    
+    /**
+     * Registers an event handler to this Grid. The Grid class allows 
+     * registration of listeners which will be notified as a {@link SpreadsheetCell}'s value 
+     * will change.
+     *
+     * @param <E>
+     * @param eventType the type of the events to receive by the handler
+     * @param eventHandler the handler to register
+     * @throws NullPointerException if the event type or handler is null
+     */
+    public <E extends GridChange> void addEventHandler(EventType<E> eventType, EventHandler<E> eventHandler);
+    
+    /**
+     * Unregisters a previously registered event handler from this Grid. One
+     * handler might have been registered for different event types, so the
+     * caller needs to specify the particular event type from which to
+     * unregister the handler.
+     *
+     * @param <E>
+     * @param eventType the event type from which to unregister
+     * @param eventHandler the handler to unregister
+     * @throws NullPointerException if the event type or handler is null
+     */
+    public <E extends GridChange> void removeEventHandler(EventType<E> eventType, EventHandler<E> eventHandler);
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/spreadsheet/GridBase.java b/src/org/controlsfx/control/spreadsheet/GridBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..16183e27d480d2516bb4ff69e53583caa118b414
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/GridBase.java
@@ -0,0 +1,414 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import com.sun.javafx.event.EventHandlerManager;
+import impl.org.controlsfx.spreadsheet.GridViewSkin;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javafx.beans.Observable;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.Event;
+import javafx.event.EventDispatchChain;
+import javafx.event.EventHandler;
+import javafx.event.EventTarget;
+import javafx.event.EventType;
+import javafx.util.Callback;
+import org.controlsfx.control.spreadsheet.SpreadsheetView.SpanType;
+
+/**
+ * A base implementation of the {@link Grid} interface.
+ * 
+ * <h3>Row Height</h3>
+ * 
+ * You can specify some row height for some of your rows at the beginning.
+ * You have to use the method {@link #setRowHeightCallback(javafx.util.Callback) }
+ * in order to specify a Callback that will give you the index of the row, and you 
+ * will give back the height of the row.
+ * <br>
+ * If you just have a {@link Map} available, you can use the {@link MapBasedRowHeightFactory}
+ * that will construct the Callback for you.
+
+* The default height is 24.0.
+ * 
+ * <h3>Cell values</h3>
+ * <p>
+ * If you want to change the value of a cell, you have to go through the API
+ * with {@link #setCellValue(int, int, Object)}. This method will verify that
+ * the value is corresponding to the {@link SpreadsheetCellType} of the cell and
+ * try to convert it if possible. It will also fire a {@link GridChange} event
+ * in order to notify all listeners that a value has changed. <br>
+ * <p>
+ * If you want to listen to those changes, you can use the
+ * {@link #addEventHandler(EventType, EventHandler)} and
+ * {@link #removeEventHandler(EventType, EventHandler)} methods. <br>
+ * A basic listener for implementing a undo/redo in the SpreadsheetView could be
+ * like that:
+ * 
+ * <pre>
+ * Grid grid = ...;
+ * Stack&lt;GridChange&gt; undoStack = ...;
+ * grid.addEventHandler(GridChange.GRID_CHANGE_EVENT, new EventHandler&lt;GridChange&gt;() {
+ *         
+ *         public void handle(GridChange change) {
+ *                 undoStack.push(change);
+ *             }
+ *         });
+ * 
+ * </pre>
+ * 
+ * 
+ * @see Grid
+ * @see GridChange
+ */
+public class GridBase implements Grid, EventTarget {
+
+    /***************************************************************************
+     * 
+     * Private Fields
+     * 
+     **************************************************************************/
+    private final ObservableList<ObservableList<SpreadsheetCell>> rows;
+
+    private int rowCount;
+    private int columnCount;
+    private Callback<Integer, Double> rowHeightFactory;
+    private final BooleanProperty locked;
+    private final EventHandlerManager eventHandlerManager = new EventHandlerManager(this);
+    private final ObservableList<String> rowsHeader;
+    private final ObservableList<String> columnsHeader;
+    private BitSet resizableRow;
+
+    /***************************************************************************
+     * 
+     * Constructor
+     * 
+     **************************************************************************/
+
+    /**
+     * Creates a grid with a fixed number of rows and columns.
+     * 
+     * @param rowCount
+     * @param columnCount
+     */
+    public GridBase(int rowCount, int columnCount) {
+        this.rowCount = rowCount;
+        this.columnCount = columnCount;
+        rowsHeader = FXCollections.observableArrayList();
+        columnsHeader = FXCollections.observableArrayList();
+        locked = new SimpleBooleanProperty(false);
+        rowHeightFactory = new MapBasedRowHeightFactory(new HashMap<>());
+        rows = FXCollections.observableArrayList();
+        rows.addListener((Observable observable) -> {
+            setRowCount(rows.size());
+        });
+        resizableRow = new BitSet(rowCount);
+        resizableRow.set(0, rowCount, true);
+    }
+
+    /***************************************************************************
+     * 
+     * Public Methods (Inherited from Grid)
+     * 
+     **************************************************************************/
+
+    /** {@inheritDoc} */
+    @Override
+    public ObservableList<ObservableList<SpreadsheetCell>> getRows() {
+        return rows;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setCellValue(int row, int column, Object value) {
+        if (row < rowCount && column < columnCount && !isLocked()) {
+            SpreadsheetCell cell = getRows().get(row).get(column);
+            Object previousItem = cell.getItem();
+            Object convertedValue = cell.getCellType().convertValue(value);
+            cell.setItem(convertedValue);
+            if (!java.util.Objects.equals(previousItem, cell.getItem())) {
+                GridChange cellChange = new GridChange(row, column, previousItem, convertedValue);
+                Event.fireEvent(this, cellChange);
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getRowCount() {
+        return rowCount;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getColumnCount() {
+        return columnCount;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public SpanType getSpanType(final SpreadsheetView spv, final int row, final int column) {
+        if (row < 0 || column < 0 || row >= rowCount || column >= columnCount) {
+            return SpanType.NORMAL_CELL;
+        }
+        
+        final SpreadsheetCell cell =  getRows().get(row).get(column);
+
+        final int cellColumn = cell.getColumn();
+        final int cellRow = cell.getRow();
+        final int cellRowSpan = cell.getRowSpan();
+
+        if (cellColumn == column && cellRow == row && cellRowSpan == 1) {
+            return SpanType.NORMAL_CELL;
+        }
+
+        final int cellColumnSpan = cell.getColumnSpan();
+        /**
+         * This is a consuming operation so we place it after the normal_cell
+         * case since this is the most typical case.
+         */
+        final GridViewSkin skin = spv.getCellsViewSkin();
+        final boolean containsRowMinusOne = skin == null ? true : skin.containsRow(row - 1);
+        if (containsRowMinusOne && cellColumnSpan > 1 && cellColumn != column && cellRowSpan > 1
+                && cellRow != row) {
+            return SpanType.BOTH_INVISIBLE;
+        } else if (cellRowSpan > 1 && cellColumn == column) {
+            if ((cellRow == row || !containsRowMinusOne)) {
+                return SpanType.ROW_VISIBLE;
+            } else {
+                return SpanType.ROW_SPAN_INVISIBLE;
+            }
+        } else if (cellColumnSpan > 1 && cellColumn != column && (cellRow == row || !containsRowMinusOne)) {
+            return SpanType.COLUMN_SPAN_INVISIBLE;
+        } else {
+            return SpanType.NORMAL_CELL;
+        }
+    }
+
+    /**
+     * Return the height of a row. 
+     * It will first look into the {@link Callback}provided at the
+     * initialization. If nothing's found, {@link #AUTOFIT} will be returned.
+     * @param row
+     * @return the height of a row.
+     */
+    @Override
+    public double getRowHeight(int row) {
+        return rowHeightFactory.call((Integer) row);
+    }
+
+    /***************************************************************************
+     * 
+     * Public Methods
+     * 
+     **************************************************************************/
+
+    /**
+     * Set a new {@link Callback} for this grid in order to specify height of
+     * each row.
+     * 
+     * @param rowHeight
+     */
+    public void setRowHeightCallback(Callback<Integer, Double> rowHeight) {
+        this.rowHeightFactory = rowHeight;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public ObservableList<String> getRowHeaders() {
+        return rowsHeader;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public ObservableList<String> getColumnHeaders() {
+        return columnsHeader;
+    }
+
+    /**
+     * Return a BooleanProperty associated with the locked grid state. It means
+     * that the Grid is in a read-only mode and that no SpreadsheetCell can be
+     * modified, no regards for their own
+     * {@link SpreadsheetCell#isEditable()} state.
+     * 
+     * @return a BooleanProperty associated with the locked grid state.
+     */
+    public BooleanProperty lockedProperty() {
+        return locked;
+    }
+
+    /**
+     * Return whether this Grid id locked or not.
+     * 
+     * @return whether this Grid id locked or not.
+     */
+    public boolean isLocked() {
+        return locked.get();
+    }
+
+    /**
+     * Lock or unlock this Grid.
+     * 
+     * @param lock
+     */
+    public void setLocked(Boolean lock) {
+        locked.setValue(lock);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void spanRow(int count, int rowIndex, int colIndex) {
+        if (count <= 0 || count > rowCount || rowIndex >= rowCount || colIndex >= columnCount) {
+            return;
+        }
+        final SpreadsheetCell cell = rows.get(rowIndex).get(colIndex);
+        final int colSpan = cell.getColumnSpan();
+        final int rowSpan = count;
+        cell.setRowSpan(rowSpan);
+        for (int row = rowIndex; row < rowIndex + rowSpan && row < rowCount; ++row) {
+            for (int col = colIndex; col < colIndex + colSpan && col < columnCount; ++col) {
+                if (row != rowIndex || col != colIndex) {
+                    rows.get(row).set(col, cell);
+                }
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void spanColumn(int count, int rowIndex, int colIndex) {
+        if (count <= 0 || count > columnCount || rowIndex >= rowCount || colIndex >= columnCount) {
+            return;
+        }
+        final SpreadsheetCell cell = rows.get(rowIndex).get(colIndex);
+        final int colSpan = count;
+        final int rowSpan = cell.getRowSpan();
+        cell.setColumnSpan(colSpan);
+        for (int row = rowIndex; row < rowIndex + rowSpan && row < rowCount; ++row) {
+            for (int col = colIndex; col < colIndex + colSpan && col < columnCount; ++col) {
+                if (row != rowIndex || col != colIndex) {
+                    rows.get(row).set(col, cell);
+                }
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setRows(Collection<ObservableList<SpreadsheetCell>> rows) {
+        this.rows.clear();
+        this.rows.addAll(rows);
+
+        setRowCount(rows.size());
+        setColumnCount(rowCount == 0 ? 0 : this.rows.get(0).size());
+    }
+
+    /**
+     * Sets the resizable state of all rows. If a bit is set to true in the
+     * BitSet, it means the row is resizable.
+     *
+     * The {@link BitSet#length() } must be equal to the {@link #getRowCount() }
+     *
+     * @param resizableRow
+     */
+    public void setResizableRows(BitSet resizableRow) {
+        this.resizableRow = resizableRow;
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public boolean isRowResizable(int row) {
+        return resizableRow.get(row);
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public <E extends GridChange> void addEventHandler(EventType<E> eventType, EventHandler<E> eventHandler) {
+        eventHandlerManager.addEventHandler(eventType, eventHandler);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public <E extends GridChange> void removeEventHandler(EventType<E> eventType, EventHandler<E> eventHandler) {
+        eventHandlerManager.removeEventHandler(eventType, eventHandler);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public EventDispatchChain buildEventDispatchChain(EventDispatchChain tail) {
+        return tail.append(eventHandlerManager);
+    }
+
+    /***************************************************************************
+     * 
+     * Private implementation
+     * 
+     **************************************************************************/
+
+    /**
+     * Set a new rowCount for the grid.
+     * 
+     * @param rowCount
+     */
+    private void setRowCount(int rowCount) {
+        this.rowCount = rowCount;
+    }
+
+    /**
+     * Set a new columnCount for the grid.
+     * 
+     * @param columnCount
+     */
+    private void setColumnCount(int columnCount) {
+        this.columnCount = columnCount;
+    }
+
+    /**
+     * This class serves as a bridge between row height Callback needed by the
+     * GridBase and a Map&lt;Integer,Double&gt; that one could have (each Integer
+     * specify a row index and its associated height).
+     */
+    public static class MapBasedRowHeightFactory implements Callback<Integer, Double> {
+        private final Map<Integer, Double> rowHeightMap;
+
+        public MapBasedRowHeightFactory(Map<Integer, Double> rowHeightMap) {
+            this.rowHeightMap = rowHeightMap;
+        }
+
+        @Override
+        public Double call(Integer index) {
+            Double value = rowHeightMap.get(index);
+            return value == null ? AUTOFIT : value;
+        }
+
+    }
+}
diff --git a/src/org/controlsfx/control/spreadsheet/GridChange.java b/src/org/controlsfx/control/spreadsheet/GridChange.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8ee2ffaccf0ee574e9d7462059ec195fceed450
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/GridChange.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2013, ControlsFX 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met: *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. * Redistributions in binary
+ * form must reproduce the above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or other materials provided
+ * with the distribution. * Neither the name of ControlsFX, any associated
+ * website, nor the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import java.io.Serializable;
+
+import javafx.event.Event;
+import javafx.event.EventType;
+
+/**
+ * This class represents a single change happening in a {@link Grid}.
+ * 
+ * @see Grid
+ * @see GridBase
+ */
+public class GridChange extends Event implements Serializable {
+
+    /**
+     * This is the event used by {@link GridChange}.
+     */
+    public static final EventType<GridChange> GRID_CHANGE_EVENT = new EventType<>(Event.ANY, "GridChange"); //$NON-NLS-1$
+
+    /**
+     * *************************************************************************
+     * * Static field * *
+     ************************************************************************* 
+     */
+    private static final long serialVersionUID = 210644901287223524L;
+
+    /**
+     * *************************************************************************
+     * * Private Fields * *
+     ************************************************************************* 
+     */
+    private final int row;
+    private final int column;
+    private final Object oldValue;
+    private final Object newValue;
+
+    /**
+     * *************************************************************************
+     * * Constructor *
+     ************************************************************************* 
+     */
+    /**
+     * Constructor of a GridChange when a change inside a
+     * {@link SpreadsheetCell} is happening.
+     * 
+     * @param row
+     * @param column
+     * @param oldValue
+     * @param newValue
+     */
+    public GridChange(int row, int column, Object oldValue, Object newValue) {
+        super(GRID_CHANGE_EVENT);
+        this.row = row;
+        this.column = column;
+        this.oldValue = oldValue;
+        this.newValue = newValue;
+    }
+
+    /**
+     * *************************************************************************
+     * * Public methods * *
+     ************************************************************************* 
+     */
+    /**
+     * Return the row number of this change.
+     * 
+     * @return the row number of this change.
+     */
+    public int getRow() {
+        return row;
+    }
+
+    /**
+     * Return the column number of this change.
+     * 
+     * @return the column number of this change.
+     */
+    public int getColumn() {
+        return column;
+    }
+
+    /**
+     * Return the value before the change.
+     * 
+     * @return the value before the change.
+     */
+    public Object getOldValue() {
+        return oldValue;
+    }
+
+    /**
+     * Return the value after the change.
+     * 
+     * @return the value after the change.
+     */
+    public Object getNewValue() {
+        return newValue;
+    }
+}
diff --git a/src/org/controlsfx/control/spreadsheet/Picker.java b/src/org/controlsfx/control/spreadsheet/Picker.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c2762da12248a7376f5f69a7e0f566f6747d05b
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/Picker.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import java.util.Collection;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+/**
+ *
+ * Pickers can display some Images next to the headers. <br>
+ * You can specify the image by providing custom StyleClass :<br>
+ * 
+ * <pre>
+ * .picker-label{
+ *   -fx-graphic: url("add.png"); 
+ *   -fx-background-color: white;
+ *   -fx-padding: 0 0 0 0;
+ * }
+ * </pre>
+ * 
+ * The {@link #onClick() } method does nothing by default, so you can override it
+ * if you want to execute a custom action when the user will click on your Picker.
+ * 
+ * <h3>Visual:</h3> <center><img src="pickers.PNG" alt="Screenshot of Picker"></center>
+ * 
+ */
+public class Picker {
+
+    private final ObservableList<String> styleClass = FXCollections.observableArrayList();
+
+    /**
+     * Default constructor, the default "picker-label" styleClass is applied.
+     */
+    public Picker() {
+        this("picker-label"); //$NON-NLS-1$
+    }
+
+    /**
+     * Initialize this Picker with the style classes provided.
+     * @param styleClass 
+     */
+    public Picker(String... styleClass) {
+        this.styleClass.addAll(styleClass);
+    }
+    
+    /**
+     * Initialize this Picker with the style classes provided.
+     * @param styleClass 
+     */
+    public Picker(Collection<String> styleClass) {
+        this.styleClass.addAll(styleClass);
+    }
+
+
+    /**
+     * @return the style class of this picker.
+     */
+    public final ObservableList<String> getStyleClass() {
+        return styleClass;
+    }
+
+    /**
+     * This method will be called whenever the user clicks on this picker.
+     */
+    public void onClick(){
+        //no-op by default
+    }
+}
diff --git a/src/org/controlsfx/control/spreadsheet/SpreadsheetCell.java b/src/org/controlsfx/control/spreadsheet/SpreadsheetCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..29bb9ad7cd645418a15947000a53b2d2741e4976
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/SpreadsheetCell.java
@@ -0,0 +1,333 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import java.util.Optional;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.ObservableSet;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.event.EventType;
+import javafx.scene.Node;
+
+/**
+ *
+ * Interface of the cells used in the {@link SpreadsheetView}.
+ * 
+ * See {@link SpreadsheetCellBase} for a complete and detailed documentation.
+ * @see SpreadsheetCellBase
+ */
+public interface SpreadsheetCell {
+    /**
+     * This EventType can be used with an {@link EventHandler} in order to catch
+     * when the editable state of a SpreadsheetCell is changed.
+     */
+    public static final EventType EDITABLE_EVENT_TYPE = new EventType("EditableEventType"); //$NON-NLS-1$
+    
+    /**
+     * This EventType can be used with an {@link EventHandler} in order to catch
+     * when the wrap text state of a SpreadsheetCell is changed.
+     */
+    public static final EventType WRAP_EVENT_TYPE = new EventType("WrapTextEventType"); //$NON-NLS-1$
+    
+    /**
+     * This EventType can be used with an {@link EventHandler} in order to catch
+     * when a corner state of a SpreadsheetCell is changed.
+     */
+    public static final EventType CORNER_EVENT_TYPE = new EventType("CornerEventType"); //$NON-NLS-1$
+
+    /**
+     * This enum states the four different corner available for positioning 
+     * some elements in a cell.
+     */
+    public static enum CornerPosition {
+
+        TOP_LEFT ,
+        TOP_RIGHT ,
+        BOTTOM_RIGHT ,
+        BOTTOM_LEFT 
+    }
+    
+    /**
+     * Verify that the upcoming cell value can be set to the current cell. This
+     * is currently used by the Copy/Paste.
+     *
+     * @param cell
+     * @return true if the upcoming cell value can be set to the current cell.
+     */
+    public boolean match(SpreadsheetCell cell);
+
+    /**
+     * Sets the value of the property Item. This should be used only at
+     * initialization. Prefer {@link Grid#setCellValue(int, int, Object)} after
+     * because it will compute correctly the modifiedCell. If
+     * {@link #isEditable()} return false, nothing is done.
+     *
+     * @param value
+     */
+    public void setItem(Object value);
+
+    /**
+     * Return the value contained in the cell.
+     *
+     * @return the value contained in the cell.
+     */
+    public Object getItem();
+
+    /**
+     * The item property represents the currently-set value inside this
+     * SpreadsheetCell instance.
+     *
+     * @return the item property which contains the value.
+     */
+    public ObjectProperty<Object> itemProperty();
+
+    /**
+     * Return if this cell can be edited or not.
+     *
+     * @return true if this cell is editable.
+     */
+    public boolean isEditable();
+
+    /**
+     * Change the editable state of this cell
+     *
+     * @param editable
+     */
+    public void setEditable(boolean editable);
+    
+    /**
+     * If a run of text exceeds the width of the Labeled, then this variable
+     * indicates whether the text should wrap onto another line.
+     *
+     * @return the value of wrapText property.
+     */
+    public boolean isWrapText();
+
+    /**
+     * If a run of text exceeds the width of the Labeled, then this variable
+     * indicates whether the text should wrap onto another line.
+     * @param wrapText
+     */
+    public void setWrapText(boolean wrapText);
+
+    /**
+     * A string representation of the CSS style associated with this specific
+     * Node. This is analogous to the "style" attribute of an HTML element. Note
+     * that, like the HTML style attribute, this variable contains style
+     * properties and values and not the selector portion of a style rule.
+     *
+     * @param style
+     */
+    public void setStyle(String style);
+    
+    /**
+     * A string representation of the CSS style associated with this specific
+     * Node. This is analogous to the "style" attribute of an HTML element. Note
+     * that, like the HTML style attribute, this variable contains style
+     * properties and values and not the selector portion of a style rule.
+     *
+     * @return The inline CSS style associated with this Node. If this Node does
+     * not have an inline style, an empty String is returned.
+     */
+    public String getStyle();
+    
+    /**
+     * A string representation of the CSS style associated with this specific
+     * Node. This is analogous to the "style" attribute of an HTML element. Note
+     * that, like the HTML style attribute, this variable contains style
+     * properties and values and not the selector portion of a style rule.
+     *
+     * @return a string representation of the CSS style
+     */
+    public StringProperty styleProperty();
+    
+    /**
+     * This activate the given cornerPosition.
+     * @param position
+     */
+    public void activateCorner(CornerPosition position);
+    
+    /**
+     * This deactivate the given cornerPosition.
+     * @param position
+     */
+    public void deactivateCorner(CornerPosition position);
+
+    /**
+     * 
+     * @param position
+     * @return the current state of a specific corner.
+     */
+    public boolean isCornerActivated(CornerPosition position);
+    
+    /**
+     * The {@link StringProperty} linked with the format.
+     *
+     * @return The {@link StringProperty} linked with the format state.
+     */
+    public StringProperty formatProperty();
+
+    /**
+     * Return the format of this cell or an empty string if no format has been
+     * specified.
+     *
+     * @return Return the format of this cell or an empty string if no format
+     * has been specified.
+     */
+    public String getFormat();
+
+    /**
+     * Set a new format for this Cell. You can specify how to represent the
+     * value in the cell.
+     *
+     * @param format
+     */
+    public void setFormat(String format);
+
+    /**
+     * Return the StringProperty of the representation of the value.
+     *
+     * @return the StringProperty of the representation of the value.
+     */
+    public ReadOnlyStringProperty textProperty();
+
+    /**
+     * Return the String representation currently used for display in the
+     * {@link SpreadsheetView}.
+     *
+     * @return text representation of the value.
+     */
+    public String getText();
+
+    /**
+     * Return the {@link SpreadsheetCellType} of this particular cell.
+     *
+     * @return the {@link SpreadsheetCellType} of this particular cell.
+     */
+    public SpreadsheetCellType getCellType();
+
+    /**
+     * Return the row of this cell.
+     *
+     * @return the row of this cell.
+     */
+    public int getRow();
+
+    /**
+     * Return the column of this cell.
+     *
+     * @return the column of this cell.
+     */
+    public int getColumn();
+
+    /**
+     * Return how much this cell is spanning in row, 1 is normal.
+     *
+     * @return how much this cell is spanning in row, 1 is normal.
+     */
+    public int getRowSpan();
+
+    /**
+     * Sets how much this cell is spanning in row. See {@link SpreadsheetCell}
+     * description for information. You should use
+     * {@link Grid#spanRow(int, int, int)} instead of using this method
+     * directly.
+     *
+     * @param rowSpan
+     */
+    public void setRowSpan(int rowSpan);
+
+    /**
+     * Return how much this cell is spanning in column, 1 is normal.
+     *
+     * @return how much this cell is spanning in column, 1 is normal.
+     */
+    public int getColumnSpan();
+
+    /**
+     * Sets how much this cell is spanning in column. See
+     * {@link SpreadsheetCell} description for information. You should use
+     * {@link Grid#spanColumn(int, int, int)} instead of using this method
+     * directly.
+     *
+     * @param columnSpan
+     */
+    public void setColumnSpan(int columnSpan);
+
+    /**
+     * Return an ObservableList of String of all the style class associated with
+     * this cell. You can easily modify its appearance by adding a style class
+     * (previously set in CSS).
+     *
+     * @return an ObservableList of String of all the style class
+     */
+    public ObservableSet<String> getStyleClass();
+
+    /**
+     * @return an ObjectProperty wrapping a Node for the graphic.
+     */
+    public ObjectProperty<Node> graphicProperty();
+
+    /**
+     * Set a graphic for this cell to display aside with the text.
+     *
+     * @param graphic
+     */
+    public void setGraphic(Node graphic);
+
+    /**
+     * Return the graphic node associated with this cell. Return null if nothing
+     * has been associated.
+     *
+     * @return the graphic node associated with this cell.
+     */
+    public Node getGraphic();
+    
+    /**
+     * @return the tooltip associated with this SpreadsheetCell.
+     */
+    public Optional<String> getTooltip();
+    
+    /**
+     * Registers an event handler to this SpreadsheetCell. 
+     * @param eventType the type of the events to receive by the handler
+     * @param eventHandler the handler to register
+     * @throws NullPointerException if the event type or handler is null
+     */
+    public void addEventHandler(EventType<Event> eventType, EventHandler<Event> eventHandler);
+    
+    /**
+     * Unregisters a previously registered event handler from this SpreadsheetCell. 
+     * @param eventType the event type from which to unregister
+     * @param eventHandler the handler to unregister
+     * @throws NullPointerException if the event type or handler is null
+     */
+    public void removeEventHandler(EventType<Event> eventType, EventHandler<Event> eventHandler);
+}
diff --git a/src/org/controlsfx/control/spreadsheet/SpreadsheetCellBase.java b/src/org/controlsfx/control/spreadsheet/SpreadsheetCellBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..f13634f36c40d4a569ff38646dfac194b67f4600
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/SpreadsheetCellBase.java
@@ -0,0 +1,643 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import com.sun.javafx.event.EventHandlerManager;
+import java.util.Objects;
+import java.util.Optional;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyStringProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableSet;
+import javafx.event.Event;
+import javafx.event.EventDispatchChain;
+import javafx.event.EventHandler;
+import javafx.event.EventTarget;
+import javafx.event.EventType;
+import javafx.scene.Node;
+import javafx.scene.image.ImageView;
+
+/**
+ * The SpreadsheetCells serve as model for the {@link SpreadsheetView}. <br>
+ * You will provide them when constructing a {@link Grid}.
+ * 
+ * <br>
+ * <h3>SpreadsheetCell Types</h3> Each SpreadsheetCell has its own
+ * {@link SpreadsheetCellType} which has its own {@link SpreadsheetCellEditor}
+ * in order to control very closely the possible modifications.
+ * 
+ * <p>
+ * Different {@link SpreadsheetCellType SpreadsheetCellTypes} are available
+ * depending on the data you want to represent in your {@link SpreadsheetView}.
+ * You can use the different static method provided in
+ * {@link SpreadsheetCellType} in order to create the specialized
+ * SpreadsheetCell that suits your need.
+ * 
+ * 
+ * <br>
+ * 
+ * <p>
+ * If you want to create a SpreadsheetCell of your own, you simply have to
+ * use one of the provided constructor. Usually you will let your {@link SpreadsheetCellType}
+ * create the cells. For example 
+ * {@link SpreadsheetCellType.StringType#createCell(int, int, int, int, java.lang.String) }.
+ * You will also have to provide a custom {@link SpreadsheetCellEditor}.
+ * 
+ * <h2>Configuration</h2>
+ * You will have to indicate the coordinates of the cell together with the
+ * {@link #setRowSpan(int) row} and {@link #setColumnSpan(int) column} span. You
+ * can specify if you want the cell to be editable or not using
+ * {@link #setEditable(boolean)}. Be advised that a cell with a rowSpan means
+ * that the cell will replace all the cells situated in the rowSpan range. Same
+ * with the column span. 
+ * <br>
+ * So the best way to handle spanning is to fill your grid
+ * with unique cells, and then call at the end {@link GridBase#spanColumn(int, int, int)}
+ * or {@link GridBase#spanRow(int, int, int)}. These methods will handle the span
+ * for you.
+ * 
+ * <br>
+ * 
+ * <h3>Format</h3>
+ * Your cell can have its very own format. If you want to display some dates
+ * with different format, you just have to create a unique
+ * {@link SpreadsheetCellType} and then specify for each cell their format with
+ * {@link #setFormat(String)}. You will then have the guaranty that all your
+ * cells will have a LocalDate as a value, but the value will be displayed
+ * differently for each cell. This will also guaranty that copy/paste and other
+ * operation will be compatible since every cell will share the same
+ * {@link SpreadsheetCellType}. <br>
+ * Here an example : <br>
+ * 
+ * 
+ * <pre>
+ * SpreadsheetCell cell = SpreadsheetCellType.DATE.createCell(row, column, rowSpan, colSpan,
+ *         LocalDate.now().plusDays((int) (Math.random() * 10))); // Random value
+ * // given here
+ * final double random = Math.random();
+ * if (random &lt; 0.25) {
+ *     cell.setFormat(&quot;EEEE d&quot;);
+ * } else if (random &lt; 0.5) {
+ *     cell.setFormat(&quot;dd/MM :YY&quot;);
+ * } else {
+ *     cell.setFormat(&quot;dd/MM/YYYY&quot;);
+ * }
+ * </pre>
+ * 
+ * <center><img src="dateFormat.PNG" alt="SpreadsheetCellBase with custom format"></center>
+ * 
+ * <h3>Graphic</h3>
+ * Each cell can have a graphic to display next to the text in the cells. Just
+ * use the {@link #setGraphic(Node)} in order to specify the graphic you want.
+ * If you specify an {@link ImageView}, the SpreadsheetView will try to resize it in
+ * order to fit the space available in the cell.
+ * 
+ * For example :
+ * 
+ * <pre>
+ * cell.setGraphic(new ImageView(new Image(getClass().getResourceAsStream(&quot;icons/exclamation.png&quot;))));
+ * </pre>
+ * 
+ * <center><img src="graphicNodeToCell.png" alt="SpreadsheetCellBase with graphic"></center> <br>
+ * In addition to that, you can also specify another graphic property to your
+ * cell with {@link #activateCorner(org.controlsfx.control.spreadsheet.SpreadsheetCell.CornerPosition) }.
+ * This allow you to activate or deactivate some graphics on the cell in every 
+ * corner. Right now it's a little red triangle but you can modify this in your CSS by
+ * using the "<b>cell-corner</b>" style class.
+ * 
+ * <pre>
+ * .cell-corner.top-left{
+ *     -fx-background-color: red;
+ *     -fx-shape : "M 0 0 L 1 0 L 0 1 z";
+ * }
+ * </pre>
+ * 
+ * <center><img src="triangleCell.PNG" alt="SpreadsheetCellBase with a styled cell-corner"></center>
+ * 
+ * 
+ * <br>
+ * You can also customize the tooltip of your SpreadsheetCell by specifying one
+ * with {@link #setTooltip(java.lang.String) }.
+ * 
+ * <h3>Style with CSS</h3>
+ * You can style your cell by specifying some styleClass with
+ * {@link #getStyleClass()}. You just have to create and custom that class in
+ * your CSS stylesheet associated with your {@link SpreadsheetView}. Also note
+ * that all {@link SpreadsheetCell} have a "<b>spreadsheet-cell</b>" styleClass
+ * added by default. Here is a example :<br>
+ * 
+ * <pre>
+ * cell.getStyleClass().add(&quot;row_header&quot;);
+ * </pre>
+ * 
+ * And in the CSS:
+ * 
+ * <pre>
+ *  .spreadsheet-cell.row_header{
+ *     -fx-background-color: #b4d4ad ;
+ *     -fx-background-insets: 0, 0 1 1 0;
+ *     -fx-alignment: center;
+ * }
+ * </pre>
+ * 
+ * <h3>Examples</h3>
+ * Here is an example that uses all the pre-built {@link SpreadsheetCellType}
+ * types. The generation is random here so you will want to replace the logic to
+ * suit your needs.
+ * 
+ * <pre>
+ * private SpreadsheetCell&lt;?&gt; generateCell(int row, int column, int rowSpan, int colSpan) {
+ *     List&lt;String&gt; stringListTextCell = Arrays.asList("Shanghai","Paris","New York City","Bangkok","Singapore","Johannesburg","Berlin","Wellington","London","Montreal");
+ *     final double random = Math.random();
+ *     if (random &lt; 0.10) {
+ *         List&lt;String&gt; stringList = Arrays.asList("China","France","New Zealand","United States","Germany","Canada");
+ *         cell = SpreadsheetCellType.LIST(stringList).createCell(row, column, rowSpan, colSpan, stringList.get((int) (Math.random() * 6)));
+ *     } else if (random &gt;= 0.10 &amp;&amp; random &lt; 0.25) {
+ *         cell = SpreadsheetCellType.STRING.createCell(row, column, rowSpan, colSpan,stringListTextCell.get((int)(Math.random()*10)));
+ *     } else if (random &gt;= 0.25 &amp;&amp; random &lt; 0.75) {
+ *         cell = SpreadsheetCellType.DOUBLE.createCell(row, column, rowSpan, colSpan,(double)Math.round((Math.random()*100)*100)/100);
+ *     } else {
+ *         cell = SpreadsheetCellType.DATE.createCell(row, column, rowSpan, colSpan, LocalDate.now().plusDays((int)(Math.random()*10)));
+ *     }
+ *     return cell;
+ * }
+ * </pre>
+ * 
+ * @see SpreadsheetView
+ * @see SpreadsheetCellEditor
+ * @see SpreadsheetCellType
+ */
+public class SpreadsheetCellBase implements SpreadsheetCell, EventTarget{
+
+    /***************************************************************************
+     * 
+     * Private Fields
+     * 
+     **************************************************************************/
+
+    //The Bit position for the editable Property.
+    private static final int EDITABLE_BIT_POSITION = 4;
+    private static final int WRAP_BIT_POSITION = 5;
+    private final SpreadsheetCellType type;
+    private final int row;
+    private final int column;
+    private int rowSpan;
+    private int columnSpan;
+    private final StringProperty format;
+    private final StringProperty text;
+    private final StringProperty styleProperty;
+    private final ObjectProperty<Node> graphic;
+    private String tooltip;
+    /**
+     * This variable handles all boolean values of this SpreadsheetCell inside
+     * its bits. Instead of using regular boolean, we use that int so that we 
+     * can reduce memory usage to the bare minimum.
+     */
+    private int propertyContainer = 0;
+    private final EventHandlerManager eventHandlerManager = new EventHandlerManager(this);
+
+    private ObservableSet<String> styleClass;
+
+    /***************************************************************************
+     * 
+     * Constructor
+     * 
+     **************************************************************************/
+
+    /**
+     * Constructs a SpreadsheetCell with the given configuration.
+     * Use the {@link SpreadsheetCellType#OBJECT} type.
+     * @param row
+     * @param column
+     * @param rowSpan
+     * @param columnSpan
+     */
+    public SpreadsheetCellBase(final int row, final int column, final int rowSpan, final int columnSpan) {
+        this(row, column, rowSpan, columnSpan, SpreadsheetCellType.OBJECT);
+    }
+
+    /**
+     * Constructs a SpreadsheetCell with the given configuration.
+     * 
+     * @param row
+     * @param column
+     * @param rowSpan
+     * @param columnSpan
+     * @param type
+     */
+    public SpreadsheetCellBase(final int row, final int column, final int rowSpan, final int columnSpan,
+            final SpreadsheetCellType<?> type) {
+        this.row = row;
+        this.column = column;
+        this.rowSpan = rowSpan;
+        this.columnSpan = columnSpan;
+        this.type = type;
+        text = new SimpleStringProperty(""); //$NON-NLS-1$
+        format = new SimpleStringProperty(""); //$NON-NLS-1$
+        graphic = new SimpleObjectProperty<>();
+        format.addListener(new ChangeListener<String>() {
+            @Override
+            public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) {
+                updateText();
+            }
+        });
+        //Editable is true at the initialisation
+        setEditable(true);
+        getStyleClass().add("spreadsheet-cell"); //$NON-NLS-1$
+        styleProperty = new SimpleStringProperty();
+    }
+
+   /***************************************************************************
+     * 
+     * Public Methods
+     * 
+     **************************************************************************/
+    
+    /** {@inheritDoc} */
+    @Override
+    public boolean match(SpreadsheetCell cell) {
+        return type.match(cell);
+    }
+
+    // --- item
+    private final ObjectProperty<Object> item = new SimpleObjectProperty<Object>(this, "item") { //$NON-NLS-1$
+        @Override
+        protected void invalidated() {
+            updateText();
+        }
+    };
+
+   /** {@inheritDoc} */
+    @Override
+    public final void setItem(Object value) {
+        if (isEditable())
+            item.set(value);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final Object getItem() {
+        return item.get();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final ObjectProperty<Object> itemProperty() {
+        return item;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final boolean isEditable() {
+        return isSet(EDITABLE_BIT_POSITION);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void setEditable(boolean editable) {
+        if(setMask(editable, EDITABLE_BIT_POSITION)){
+            Event.fireEvent(this, new Event(EDITABLE_EVENT_TYPE));
+        }
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public boolean isWrapText(){
+        return isSet(WRAP_BIT_POSITION);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setWrapText(boolean wrapText) {
+        if (setMask(wrapText, WRAP_BIT_POSITION)) {
+            Event.fireEvent(this, new Event(WRAP_EVENT_TYPE));
+        }
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public final StringProperty formatProperty() {
+        return format;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final String getFormat() {
+        return format.get();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void setFormat(String format) {
+        formatProperty().set(format);
+        updateText();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final ReadOnlyStringProperty textProperty() {
+        return text;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final String getText() {
+        return text.get();
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public final SpreadsheetCellType getCellType() {
+        return type;
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public final int getRow() {
+        return row;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final int getColumn() {
+        return column;
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public final int getRowSpan() {
+        return rowSpan;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void setRowSpan(int rowSpan) {
+        this.rowSpan = rowSpan;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final int getColumnSpan() {
+        return columnSpan;
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public final void setColumnSpan(int columnSpan) {
+        this.columnSpan = columnSpan;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final ObservableSet<String> getStyleClass() {
+        if (styleClass == null) {
+            styleClass = FXCollections.observableSet();
+        }
+        return styleClass;
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public void setStyle(String style){
+        styleProperty.set(style);
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public String getStyle(){
+        return styleProperty.get();
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public StringProperty styleProperty(){
+        return styleProperty;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public ObjectProperty<Node> graphicProperty() {
+        return graphic;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setGraphic(Node graphic) {
+        this.graphic.set(graphic);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Node getGraphic() {
+        return graphic.get();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Optional<String> getTooltip() {
+        return Optional.ofNullable(tooltip);
+    }
+    
+    /**
+     * Set a new tooltip for this cell.
+     * @param tooltip 
+     */
+    public void setTooltip(String tooltip){
+        this.tooltip = tooltip;
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public void activateCorner(CornerPosition position) {
+        if(setMask(true, getCornerBitNumber(position))){
+            Event.fireEvent(this, new Event(CORNER_EVENT_TYPE));
+        }
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public void deactivateCorner(CornerPosition position) {
+        if(setMask(false, getCornerBitNumber(position))){
+             Event.fireEvent(this, new Event(CORNER_EVENT_TYPE));
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isCornerActivated(CornerPosition position) {
+        return isSet(getCornerBitNumber(position));
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    public EventDispatchChain buildEventDispatchChain(EventDispatchChain tail) {
+        return tail.append(eventHandlerManager);
+    }
+    
+    /***************************************************************************
+     * 
+     * Overridden Methods
+     * 
+     **************************************************************************/
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return "cell[" + row + "][" + column + "]" + rowSpan + "-" + columnSpan; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!(obj instanceof SpreadsheetCell))
+            return false;
+
+        final SpreadsheetCell otherCell = (SpreadsheetCell) obj;
+        return otherCell.getRow() == row && otherCell.getColumn() == column
+                && Objects.equals(otherCell.getText(), getText())
+                && rowSpan == otherCell.getRowSpan()
+                && columnSpan == otherCell.getColumnSpan()
+                && Objects.equals(getStyleClass(), otherCell.getStyleClass());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + column;
+        result = prime * result + row;
+        result = prime * result + rowSpan;
+        result = prime * result + columnSpan;
+        result = prime * result + Objects.hashCode(getText());
+        result = prime * result + Objects.hashCode(getStyleClass());
+        return result;
+    }
+    
+    /**
+     * Registers an event handler to this SpreadsheetCell. The SpreadsheetCell class allows 
+     * registration of listeners which will be notified when a corner state of
+     * the editable state of this SpreadsheetCell have changed.
+     *
+     * @param eventType the type of the events to receive by the handler
+     * @param eventHandler the handler to register
+     * @throws NullPointerException if the event type or handler is null
+     */
+    @Override
+    public void addEventHandler(EventType<Event> eventType, EventHandler<Event> eventHandler) {
+         eventHandlerManager.addEventHandler(eventType, eventHandler);
+    }
+
+    /**
+     * Unregisters a previously registered event handler from this SpreadsheetCell. One
+     * handler might have been registered for different event types, so the
+     * caller needs to specify the particular event type from which to
+     * unregister the handler.
+     *
+     * @param eventType the event type from which to unregister
+     * @param eventHandler the handler to unregister
+     * @throws NullPointerException if the event type or handler is null
+     */
+    @Override
+    public void removeEventHandler(EventType<Event> eventType, EventHandler<Event> eventHandler) {
+         eventHandlerManager.removeEventHandler(eventType, eventHandler);
+    }
+    
+    /***************************************************************************
+     * 
+     * Private Implementation
+     * 
+     **************************************************************************/
+
+    /**
+     * Update the text for the SpreadsheetView.
+     */
+    @SuppressWarnings("unchecked")
+    private void updateText() {
+        if(getItem() == null){
+            text.setValue(""); //$NON-NLS-1$
+        }else if (!("").equals(getFormat())) { //$NON-NLS-1$
+            text.setValue(type.toString(getItem(), getFormat()));
+        } else {
+            text.setValue(type.toString(getItem()));
+        }
+    }
+
+    /**
+     * Return the Bit position for each corner.
+     * @param position
+     * @return 
+     */
+    private int getCornerBitNumber(CornerPosition position) {
+        switch (position) {
+            case TOP_LEFT:
+                return 0;
+
+            case TOP_RIGHT:
+                return 1;
+
+            case BOTTOM_RIGHT:
+                return 2;
+
+            case BOTTOM_LEFT:
+            default:
+                return 3;
+        }
+    }
+
+    /**
+     * Set the specified bit position at the value specified by flag.
+     * @param flag
+     * @param position
+     * @return whether a change has really occured.
+     */
+    private boolean setMask(boolean flag, int position) {
+        int oldCorner = propertyContainer;
+        if (flag) {
+            propertyContainer |= (1 << position);
+        } else {
+            propertyContainer &= ~(1 << position);
+        }
+        return propertyContainer != oldCorner;
+    }
+
+    /**
+     * @param mask
+     * @param position
+     * @return whether the specified bit position is true.
+     */
+    private boolean isSet(int position) {
+        return (propertyContainer & (1 << position)) != 0;
+    }
+}
diff --git a/src/org/controlsfx/control/spreadsheet/SpreadsheetCellEditor.java b/src/org/controlsfx/control/spreadsheet/SpreadsheetCellEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..2c4aec7e60a6923329f69d2c95ddb84f66ff6a2b
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/SpreadsheetCellEditor.java
@@ -0,0 +1,927 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import impl.org.controlsfx.i18n.Localization;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.time.LocalDate;
+import java.util.List;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Control;
+import javafx.scene.control.DatePicker;
+import javafx.scene.control.IndexRange;
+import javafx.scene.control.TextArea;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.util.StringConverter;
+
+/**
+ * 
+ * SpreadsheetCellEditor are used by {@link SpreadsheetCellType} and
+ * {@link SpreadsheetCell} in order to control how each value will be entered. <br>
+ * 
+ * <h3>General behavior:</h3> Editors will be displayed if the user double-click
+ * in an editable cell ( see {@link SpreadsheetCell#setEditable(boolean)} ). <br>
+ * If the user does anything outside the editor, the editor <b> will be forced
+ * </b> to try to commit the edition and close itself. If the value is not
+ * valid, the editor will cancel the value and close itself. The editor is just
+ * here to allow communication between the user and the {@link SpreadsheetView}.
+ * It will just be given a value, and it will just give back another one after.
+ * The policy regarding validation of a given value is defined in
+ * {@link SpreadsheetCellType#match(Object)}.
+ * 
+ * If the value doesn't meet the requirements when saving the cell, nothing
+ * happens and the editor keeps editing. <br>
+ * You can abandon a current modification by pressing "esc" key. <br>
+ * 
+ * You can specify a maximum height to your spreadsheetCellEditor with {@link #getMaxHeight()
+ * }. This can be used in order to control the display of your editor. If they
+ * should grow or not in a big cell. (for example a {@link TextAreaEditor} want
+ * to grow with the cell in order to take full space for display.
+ * <br>
+ * <h3>Specific behavior:</h3> This class offers some static classes in order to
+ * create a {@link SpreadsheetCellEditor}. Here are their properties: <br>
+ * 
+ * <ul>
+ * <li> {@link StringEditor}: Basic {@link TextField}, can accept all data and
+ * save it as a string.</li>
+ * <li> {@link ListEditor}: Display a {@link ComboBox} with the different values.
+ * </li>
+ * <li> {@link DoubleEditor}: Display a {@link TextField} which accepts only
+ * double value. If the entered value is incorrect, the background will turn red
+ * so that the user will know in advance if the data will be saved or not.</li>
+ * <li> {@link IntegerEditor}: Display a {@link TextField} which accepts only
+ * Integer value. If the entered value is incorrect, the background will turn red
+ * so that the user will know in advance if the data will be saved or not.</li>
+ * <li> {@link DateEditor}: Display a {@link DatePicker}.</li>
+ * <li> {@link ObjectEditor}: Display a {@link TextField} , accept an Object.</li>
+ * </ul>
+ * 
+ * <br>
+ * <h3>Creating your editor:</h3> You can of course create your own
+ * {@link SpreadsheetCellEditor} for displaying other controls.<br>
+ * 
+ * You just have to override the four abstract methods. <b>Remember</b> that you
+ * will never call those methods directly. They will be called by the
+ * {@link SpreadsheetView} when needed.
+ * <ul>
+ * <li> {@link #startEdit(Object)}: You will configure your control with the
+ * given value which is {@link SpreadsheetCell#getItem()} converted to an
+ * object. You do not instantiate your control here, you do it in the
+ * constructor.</li>
+ * <li> {@link #getEditor()}: You will return which control you're using (for
+ * display).</li>
+ * <li> {@link #getControlValue()}: You will return the value inside your editor
+ * in order to submit it for validation.</li>
+ * <li> {@link #end()}: When editing is finished, you can properly close your own
+ * control.</li>
+ * </ul>
+ * <br>
+ * Keep in mind that you will interact only with {@link #endEdit(boolean)} where
+ * a <b>true</b> value means you want to commit, and a <b>false</b> means you
+ * want to cancel. The {@link SpreadsheetView} will handle all the rest for you
+ * and call your methods at the right moment. <br>
+ * 
+ * <h3>Use case :</h3> <center><img src="editorScheme.png" alt="Use case of SpreadsheetCellEditor"></center>
+ * 
+ * <h3>Visual:</h3>
+ * <table style="border: 1px solid gray;" summary="Screenshots of various SpreadsheetCellEditor">
+ * <tr>
+ * <td valign="center" style="text-align:right;"><strong>String</strong></td>
+ * <td><center><img src="textEditor.png" alt="Screenshot of SpreadsheetCellEditor.StringEditor"></center></td>
+ * </tr>
+ * <tr>
+ * <td valign="center" style="text-align:right;"><strong>List</strong></td>
+ * <td><center><img src="listEditor.png" alt="Screenshot of SpreadsheetCellEditor.ListEditor"></center></td>
+ * </tr>
+ * <tr>
+ * <td valign="center" style="text-align:right;"><strong>Double</strong></td>
+ * <td><center><img src="doubleEditor.png" alt="Screenshot of SpreadsheetCellEditor.DoubleEditor"></center></td>
+ * </tr>
+ * <tr>
+ * <td valign="center" style="text-align:right;"><strong>Date</strong></td>
+ * <td><center><img src="dateEditor.png" alt="Screenshot of SpreadsheetCellEditor.DateEditor"></center></td>
+ * </tr>
+ * </table>
+ * 
+ * 
+ * @see SpreadsheetView
+ * @see SpreadsheetCell
+ * @see SpreadsheetCellType
+ */
+public abstract class SpreadsheetCellEditor {
+    private static final double MAX_EDITOR_HEIGHT = 50.0;
+    
+    private static final DecimalFormat decimalFormat = new DecimalFormat("#.##########"); //$NON-NLS-1$
+    SpreadsheetView view;
+
+    /***************************************************************************
+     * * Constructor * *
+     **************************************************************************/
+
+    /**
+     * Construct the SpreadsheetCellEditor.
+     * 
+     * @param view
+     */
+    public SpreadsheetCellEditor(SpreadsheetView view) {
+        this.view = view;
+    }
+
+    /***************************************************************************
+     * * Public Final Methods * *
+     **************************************************************************/
+    /**
+     * Whenever you want to stop the edition, you call that method.<br>
+     * True means you're trying to commit the value, then
+     * {@link SpreadsheetCellType#convertValue(Object)} will be called in order
+     * to verify that the value is correct.<br>
+     * False means you're trying to cancel the value and it will be follow by
+     * {@link #end()}.<br>
+     * See SpreadsheetCellEditor description
+     * 
+     * @param b
+     *            true means commit, false means cancel
+     */
+    public final void endEdit(boolean b) {
+        view.getCellsViewSkin().getSpreadsheetCellEditorImpl().endEdit(b);
+    }
+
+    /***************************************************************************
+     * * Public Abstract Methods * *
+     **************************************************************************/
+    /**
+     * This method will be called when edition start.<br>
+     * You will then do all the configuration of your editor.
+     * 
+     * @param item
+     */
+    public abstract void startEdit(Object item);
+
+    /**
+     * Return the control used for controlling the input. This is called at the
+     * beginning in order to display your control in the cell.
+     * 
+     * @return the control used.
+     */
+    public abstract Control getEditor();
+
+    /**
+     * Return the value within your editor as a string. This will be used by the
+     * {@link SpreadsheetCellType#convertValue(Object)} in order to compute
+     * whether the value is valid regarding the {@link SpreadsheetCellType}
+     * policy.
+     * 
+     * @return the value within your editor as a string.
+     */
+    public abstract String getControlValue();
+
+    /**
+     * This method will be called at the end of edition.<br>
+     * You will be offered the possibility to do the configuration post editing.
+     */
+    public abstract void end();
+
+    /***************************************************************************
+     * * Public Methods * *
+     **************************************************************************/
+    /**
+     * Return the maximum height of the editor. 
+     * @return 50 by default.
+     */
+    public double getMaxHeight(){
+        return MAX_EDITOR_HEIGHT;
+    }
+    
+    /**
+     * A {@link SpreadsheetCellEditor} for
+     * {@link SpreadsheetCellType.ObjectType} typed cells. It displays a
+     * {@link TextField} where the user can type different values.
+     */
+    public static class ObjectEditor extends SpreadsheetCellEditor {
+
+        /***************************************************************************
+         * * Private Fields * *
+         **************************************************************************/
+        private final TextField tf;
+
+        /***************************************************************************
+         * * Constructor * *
+         **************************************************************************/
+        /**
+        * Constructor for the ObjectEditor..
+        * @param view The SpreadsheetView
+        */
+        public ObjectEditor(SpreadsheetView view) {
+            super(view);
+            tf = new TextField();
+        }
+
+        /***************************************************************************
+         * * Public Methods * *
+         **************************************************************************/
+        @Override
+        public void startEdit(Object value) { 
+        	if(value == null) tf.setText("");
+        	else if (value instanceof String) {
+            	tf.setText(value.toString());
+            }
+            attachEnterEscapeEventHandler();
+
+            tf.requestFocus();
+            tf.end();
+        }
+
+        @Override
+        public String getControlValue() {
+            return tf.getText();
+        }
+
+        @Override
+        public void end() {
+            tf.setOnKeyPressed(null);
+        }
+
+        @Override
+        public TextField getEditor() {
+            return tf;
+        }
+
+        /***************************************************************************
+         * * Private Methods * *
+         **************************************************************************/
+
+        private void attachEnterEscapeEventHandler() {
+            tf.setOnKeyPressed(new EventHandler<KeyEvent>() {
+                @Override
+                public void handle(KeyEvent t) {
+                    if (t.getCode() == KeyCode.ENTER) {
+                        endEdit(true);
+                    } else if (t.getCode() == KeyCode.ESCAPE) {
+                        endEdit(false);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * A {@link SpreadsheetCellEditor} for
+     * {@link SpreadsheetCellType.StringType} typed cells. It displays a
+     * {@link TextField} where the user can type different values.
+     */
+    public static class StringEditor extends SpreadsheetCellEditor {
+        /***************************************************************************
+         * * Private Fields * *
+         **************************************************************************/
+        private final TextField tf;
+
+        /***************************************************************************
+         * * Constructor * *
+         **************************************************************************/
+        /**
+         * Constructor for the StringEditor.
+         * @param view The SpreadsheetView
+         */
+        public StringEditor(SpreadsheetView view) {
+            super(view);
+            tf = new TextField();
+        }
+
+        /***************************************************************************
+         * * Public Methods * *
+         **************************************************************************/
+        @Override
+        public void startEdit(Object value) {
+
+            if (value instanceof String || value == null) {
+                tf.setText((String) value);
+            }
+            attachEnterEscapeEventHandler();
+
+            tf.requestFocus();
+            tf.selectAll();
+        }
+
+        @Override
+        public String getControlValue() {
+            return tf.getText();
+        }
+
+        @Override
+        public void end() {
+            tf.setOnKeyPressed(null);
+        }
+
+        @Override
+        public TextField getEditor() {
+            return tf;
+        }
+
+        /***************************************************************************
+         * * Private Methods * *
+         **************************************************************************/
+
+        private void attachEnterEscapeEventHandler() {
+            tf.setOnKeyPressed(new EventHandler<KeyEvent>() {
+                @Override
+                public void handle(KeyEvent t) {
+                    if (t.getCode() == KeyCode.ENTER) {
+                        endEdit(true);
+                    } else if (t.getCode() == KeyCode.ESCAPE) {
+                        endEdit(false);
+                    }
+                }
+            });
+        }
+    }
+
+    
+    /**
+     * A {@link SpreadsheetCellEditor} for
+     * {@link SpreadsheetCellType.StringType} typed cells. It displays a
+     * {@link TextField} where the user can type different values.
+     */
+    public static class TextAreaEditor extends SpreadsheetCellEditor {
+
+        /**
+         * *************************************************************************
+         * * Private Fields * *
+         * ************************************************************************
+         */
+        private final TextArea textArea;
+
+        /**
+         * *************************************************************************
+         * * Constructor * *
+         * ************************************************************************
+         */
+        /**
+         * Constructor for the StringEditor.
+         *
+         * @param view The SpreadsheetView
+         */
+        public TextAreaEditor(SpreadsheetView view) {
+            super(view);
+            textArea = new TextArea();
+            textArea.setWrapText(true);
+            //The textArea is not respecting the maxHeight if we are not setting the min..
+            textArea.minHeightProperty().bind(textArea.maxHeightProperty());
+        }
+
+        /**
+         * *************************************************************************
+         * * Public Methods * *
+         * ************************************************************************
+         */
+        @Override
+        public void startEdit(Object value) {
+            if (value instanceof String || value == null) {
+                textArea.setText((String) value);
+            }
+            attachEnterEscapeEventHandler();
+
+            textArea.requestFocus();
+            textArea.selectAll();
+        }
+
+        @Override
+        public String getControlValue() {
+            return textArea.getText();
+        }
+
+        @Override
+        public void end() {
+            textArea.setOnKeyPressed(null);
+        }
+
+        @Override
+        public TextArea getEditor() {
+            return textArea;
+        }
+
+        @Override
+        public double getMaxHeight() {
+            return Double.MAX_VALUE;
+        }
+        
+        /**
+         * *************************************************************************
+         * * Private Methods * *
+         * ************************************************************************
+         */
+        private void attachEnterEscapeEventHandler() {
+            
+            textArea.setOnKeyPressed(new EventHandler<KeyEvent>() {
+                @Override
+                public void handle(KeyEvent keyEvent) {
+                    if (keyEvent.getCode() == KeyCode.ENTER) {
+                        if (keyEvent.isShiftDown()) {
+                            //if shift is down, we insert a new line.
+                            textArea.replaceSelection("\n"); //$NON-NLS-1$
+                        } else {
+                            endEdit(true);
+                        }
+                    } else if (keyEvent.getCode() == KeyCode.ESCAPE) {
+                        endEdit(false);
+                    }else if(keyEvent.getCode() == KeyCode.TAB){
+                        if (keyEvent.isShiftDown()) {
+                            //if shift is down, we insert a tab.
+                            textArea.replaceSelection("\t"); //$NON-NLS-1$
+                            keyEvent.consume();
+                        } else {
+                            endEdit(true);
+                        }
+                    }
+                }
+            });
+        }
+    }
+    
+    /**
+     * A {@link SpreadsheetCellEditor} for
+     * {@link SpreadsheetCellType.DoubleType} typed cells. It displays a
+     * {@link TextField} where the user can type different numbers. Only numbers
+     * will be stored. <br>
+     * Moreover, the {@link TextField} will turn red if the value currently
+     * entered if incorrect.
+     */
+    public static class DoubleEditor extends SpreadsheetCellEditor {
+
+        /***************************************************************************
+         * * private Fields * *
+         **************************************************************************/
+        private final TextField tf;
+
+        /***************************************************************************
+         * * Constructor * *
+         **************************************************************************/
+        /**
+         * Constructor for the DoubleEditor.
+         * @param view The SpreadsheetView.
+         */
+        public DoubleEditor(SpreadsheetView view) {
+            super(view);
+            tf = new TextField() {
+                
+                @Override
+                public void insertText(int index, String text) {
+                    String fixedText = fixText(text);
+                    super.insertText(index, fixedText);
+                }
+
+                @Override
+                public void replaceText(int start, int end, String text) {
+                    String fixedText = fixText(text);
+                    super.replaceText(start, end, fixedText);
+                }
+
+                @Override
+                public void replaceText(IndexRange range, String text) {
+                    replaceText(range.getStart(), range.getEnd(), text);
+                }
+
+                private String fixText(String text) {
+                    DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(Localization.getLocale());
+                    text = text.replace(' ', '\u00a0');//$NON-NLS-1$
+                    return text.replaceAll("\\.", Character.toString(symbols.getDecimalSeparator()));//$NON-NLS-1$
+                }
+            };
+        }
+
+        /***************************************************************************
+         * * Public Methods * *
+         **************************************************************************/
+        /** {@inheritDoc} */
+        @Override
+        public void startEdit(Object value) {
+            if (value instanceof Double) {
+                //We want to set the text in its proper form regarding the Locale.
+                decimalFormat.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Localization.getLocale()));
+                tf.setText(((Double) value).isNaN() ? "" : decimalFormat.format(value)); //$NON-NLS-1$
+            } else {
+                tf.setText(null);
+            }
+
+            tf.getStyleClass().removeAll("error"); //$NON-NLS-1$
+            attachEnterEscapeEventHandler();
+
+            tf.requestFocus();
+            tf.selectAll();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void end() {
+            tf.setOnKeyPressed(null);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public TextField getEditor() {
+            return tf;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public String getControlValue() {
+            NumberFormat format = NumberFormat.getInstance(Localization.getLocale());
+            ParsePosition parsePosition = new ParsePosition(0);
+            if (tf.getText() != null) {
+                Number number = format.parse(tf.getText(), parsePosition);
+                if (number != null && parsePosition.getIndex() == tf.getText().length()) {
+                    return String.valueOf(number.doubleValue());
+                }
+            }
+            return tf.getText();
+        }
+
+        /***************************************************************************
+         * * Private Methods * *
+         **************************************************************************/
+
+        private void attachEnterEscapeEventHandler() {
+            tf.setOnKeyPressed(new EventHandler<KeyEvent>() {
+                @Override
+                public void handle(KeyEvent t) {
+                    if (t.getCode() == KeyCode.ENTER) {
+                        try {
+                            if (tf.getText().equals("")) { //$NON-NLS-1$
+                                endEdit(true);
+                            } else {
+                                tryParsing();
+                                endEdit(true);
+                            }
+                        } catch (Exception e) {
+                        }
+
+                    } else if (t.getCode() == KeyCode.ESCAPE) {
+                        endEdit(false);
+                    }
+                }
+            });
+            
+            tf.setOnKeyReleased(new EventHandler<KeyEvent>() {
+                @Override
+                public void handle(KeyEvent t) {
+                    try {
+                        if (tf.getText().equals("")) { //$NON-NLS-1$
+                            tf.getStyleClass().removeAll("error"); //$NON-NLS-1$
+                        } else {
+                            tryParsing();
+                            tf.getStyleClass().removeAll("error"); //$NON-NLS-1$
+                        }
+                    } catch (Exception e) {
+                        tf.getStyleClass().add("error"); //$NON-NLS-1$
+                    }
+                }
+            });
+        }
+        
+        private void tryParsing() throws ParseException {
+            NumberFormat format = NumberFormat.getNumberInstance(Localization.getLocale());
+            ParsePosition parsePosition = new ParsePosition(0);
+            format.parse(tf.getText(), parsePosition);
+            if (parsePosition.getIndex() != tf.getText().length()) {
+                throw new ParseException("Invalid input", parsePosition.getIndex());
+            }
+        }
+    }
+
+    /**
+     * A {@link SpreadsheetCellEditor} for
+     * {@link SpreadsheetCellType.DoubleType} typed cells. It displays a
+     * {@link TextField} where the user can type different numbers. Only numbers
+     * will be stored. <br>
+     * Moreover, the {@link TextField} will turn red if the value currently
+     * entered if incorrect.
+     */
+    public static class IntegerEditor extends SpreadsheetCellEditor {
+
+        /***************************************************************************
+         * * Private Fields * *
+         **************************************************************************/
+        private final TextField tf;
+
+        /***************************************************************************
+         * * Constructor * *
+         **************************************************************************/
+        /**
+         * Constructor for the IntegerEditor.
+         * @param view the SpreadsheetView
+         */
+        public IntegerEditor(SpreadsheetView view) {
+            super(view);
+            tf = new TextField();
+        }
+
+        /***************************************************************************
+         * * Public Methods * *
+         **************************************************************************/
+        /** {@inheritDoc} */
+        @Override
+        public void startEdit(Object value) {
+            if (value instanceof Integer) {
+                tf.setText(Integer.toString((Integer) value));
+            } else {
+                tf.setText(null);
+            }
+
+            tf.getStyleClass().removeAll("error"); //$NON-NLS-1$
+            attachEnterEscapeEventHandler();
+
+            tf.requestFocus();
+            tf.selectAll();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void end() {
+            tf.setOnKeyPressed(null);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public TextField getEditor() {
+            return tf;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public String getControlValue() {
+            return tf.getText();
+        }
+
+        /***************************************************************************
+         * * Private Methods * *
+         **************************************************************************/
+
+        private void attachEnterEscapeEventHandler() {
+            tf.setOnKeyPressed(new EventHandler<KeyEvent>() {
+                @Override
+                public void handle(KeyEvent t) {
+                    if (t.getCode() == KeyCode.ENTER) {
+                        try {
+                            if (tf.getText().equals("")) { //$NON-NLS-1$
+                                endEdit(true);
+                            } else {
+                                Integer.parseInt(tf.getText());
+                                endEdit(true);
+                            }
+                        } catch (Exception e) {
+                        }
+
+                    } else if (t.getCode() == KeyCode.ESCAPE) {
+                        endEdit(false);
+                    }
+                }
+            });
+            tf.setOnKeyReleased(new EventHandler<KeyEvent>() {
+                @Override
+                public void handle(KeyEvent t) {
+                    try {
+                        if (tf.getText().equals("")) { //$NON-NLS-1$
+                            tf.getStyleClass().removeAll("error"); //$NON-NLS-1$
+                        } else {
+                            Integer.parseInt(tf.getText());
+                            tf.getStyleClass().removeAll("error"); //$NON-NLS-1$
+                        }
+                    } catch (Exception e) {
+                        tf.getStyleClass().add("error"); //$NON-NLS-1$
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * 
+     * A {@link SpreadsheetCellEditor} for {@link SpreadsheetCellType.ListType}
+     * typed cells. It displays a {@link ComboBox} where the user can choose a
+     * value.
+     */
+    public static class ListEditor<R> extends SpreadsheetCellEditor {
+        /***************************************************************************
+         * * Private Fields * *
+         **************************************************************************/
+        private final List<String> itemList;
+        private final ComboBox<String> cb;
+        private String originalValue;
+
+        /***************************************************************************
+         * * Constructor * *
+         **************************************************************************/
+
+        /**
+         * Constructor for the ListEditor.
+         * @param view The SpreadsheetView
+         * @param itemList The items to display in the editor.
+         */
+        public ListEditor(SpreadsheetView view, final List<String> itemList) {
+            super(view);
+            this.itemList = itemList;
+            cb = new ComboBox<String>();
+            cb.setVisibleRowCount(5);
+        }
+
+        /***************************************************************************
+         * * Public Methods * *
+         **************************************************************************/
+
+        /** {@inheritDoc} */
+        @Override
+        public void startEdit(Object value) {
+            if (value instanceof String) {
+                originalValue = value.toString();
+            } else {
+                originalValue = null;
+            }
+            ObservableList<String> items = FXCollections.observableList(itemList);
+            cb.setItems(items);
+            cb.setValue(originalValue);
+
+            attachEnterEscapeEventHandler();
+            cb.show();
+            cb.requestFocus();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void end() {
+            cb.setOnKeyPressed(null);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public ComboBox<String> getEditor() {
+            return cb;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public String getControlValue() {
+            return cb.getSelectionModel().getSelectedItem();
+        }
+
+        /***************************************************************************
+         * * Private Methods * *
+         **************************************************************************/
+
+        private void attachEnterEscapeEventHandler() {
+
+            cb.setOnKeyPressed(new EventHandler<KeyEvent>() {
+                @Override
+                public void handle(KeyEvent t) {
+                    if (t.getCode() == KeyCode.ESCAPE) {
+                        cb.setValue(originalValue);
+                        endEdit(false);
+                    } else if (t.getCode() == KeyCode.ENTER) {
+                        endEdit(true);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * A {@link SpreadsheetCellEditor} for {@link SpreadsheetCellType.DateType}
+     * typed cells. It displays a {@link DatePicker} where the user can choose a
+     * date through a visual calendar.
+     */
+    public static class DateEditor extends SpreadsheetCellEditor {
+
+        /***************************************************************************
+         * * Private Fields * *
+         **************************************************************************/
+        private final DatePicker datePicker;
+        private EventHandler<KeyEvent> eh;
+        private ChangeListener<LocalDate> cl;
+        /**
+         * This is needed because "endEdit" will call our "end" method too late
+         * when pressing enter, so several "endEdit" will be called. So this
+         * prevent that to happen.
+         */
+        private boolean ending = false;
+
+        /***************************************************************************
+         * * Constructor * *
+         **************************************************************************/
+        /**
+         * Constructor for the DateEditor.
+         * @param view the SpreadsheetView
+         * @param converter A Converter for converting a date to a String.
+         */
+        public DateEditor(SpreadsheetView view, StringConverter<LocalDate> converter) {
+            super(view);
+            datePicker = new DatePicker();
+            datePicker.setConverter(converter);
+        }
+
+        /***************************************************************************
+         * * Public Methods * *
+         **************************************************************************/
+        /** {@inheritDoc} */
+        @Override
+        public void startEdit(Object value) {
+            if (value instanceof LocalDate) {
+                datePicker.setValue((LocalDate) value);
+            }
+            attachEnterEscapeEventHandler();
+            datePicker.show();
+            datePicker.getEditor().requestFocus();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void end() {
+            if (datePicker.isShowing()) {
+                datePicker.hide();
+            }
+            datePicker.removeEventFilter(KeyEvent.KEY_PRESSED, eh);
+            datePicker.valueProperty().removeListener(cl);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public DatePicker getEditor() {
+            return datePicker;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public String getControlValue() {
+            return datePicker.getEditor().getText();
+        }
+
+        /***************************************************************************
+         * * Private Methods * *
+         **************************************************************************/
+
+        private void attachEnterEscapeEventHandler() {
+            /**
+             * We need to add an EventFilter because otherwise the DatePicker
+             * will block "escape" and "enter". But when "enter" is hit, we need
+             * to runLater the commit because the value has not yet hit the
+             * DatePicker itself.
+             */
+            eh = new EventHandler<KeyEvent>() {
+                @Override
+                public void handle(KeyEvent t) {
+                    if (t.getCode() == KeyCode.ENTER) {
+                        ending = true;
+                        endEdit(true);
+                        ending = false;
+                    } else if (t.getCode() == KeyCode.ESCAPE) {
+                        endEdit(false);
+                    }
+                }
+            };
+
+            datePicker.addEventFilter(KeyEvent.KEY_PRESSED, eh);
+
+            cl = new ChangeListener<LocalDate>() {
+                @Override
+                public void changed(ObservableValue<? extends LocalDate> arg0, LocalDate arg1, LocalDate arg2) {
+                    if (!ending)
+                        endEdit(true);
+                }
+            };
+            datePicker.valueProperty().addListener(cl);
+        }
+
+    }
+}
diff --git a/src/org/controlsfx/control/spreadsheet/SpreadsheetCellType.java b/src/org/controlsfx/control/spreadsheet/SpreadsheetCellType.java
new file mode 100644
index 0000000000000000000000000000000000000000..6412af62d8d59cbc750459b3bff0c6b7471deae9
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/SpreadsheetCellType.java
@@ -0,0 +1,858 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import java.text.DecimalFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+import javafx.util.StringConverter;
+import javafx.util.converter.DefaultStringConverter;
+import javafx.util.converter.DoubleStringConverter;
+import javafx.util.converter.IntegerStringConverter;
+
+/**
+ * When instantiating a {@link SpreadsheetCell}, its SpreadsheetCellType will
+ * specify which values the cell can accept as user input, and which
+ * {@link SpreadsheetCellEditor} it will use to receive user input. <br>
+ * Different static methods are provided in order to give you access to basic
+ * types, and to create {@link SpreadsheetCell} easily:
+ * <ul>
+ * <li><b>String</b>: Accessible with
+ * {@link SpreadsheetCellType.StringType#createCell(int, int, int, int, String)}
+ * .</li>
+ * <li><b>List</b>: Accessible with
+ * {@link SpreadsheetCellType.ListType#createCell(int, int, int, int, String)}.</li>
+ * <li><b>Double</b>: Accessible with
+ * {@link SpreadsheetCellType.DoubleType#createCell(int, int, int, int, Double)}
+ * .</li>
+ * <li><b>Integer</b>: Accessible with
+ * {@link SpreadsheetCellType.IntegerType#createCell(int, int, int, int, Integer)}
+ * .</li>
+ * <li><b>Date</b>: Accessible with
+ * {@link SpreadsheetCellType.DateType#createCell(int, int, int, int, LocalDate)}
+ * .</li>
+ * </ul>
+ * 
+ * <h3>Value verification</h3> You can specify two levels of verification in your
+ * types. <br>
+ * <ul>
+ * <li>The first one is defined by {@link #match(Object)}. It is the first level
+ * that tells whether or not the given value should be accepted or not. Trying
+ * to set a String into a Double will return false for example. This method will
+ * be use by the {@link SpreadsheetView} when trying to set values for example.
+ * <br>
+ * </li>
+ * <li>The second level is defined by {@link #isError(Object)}. This is more
+ * subtle and allow you to tell whether the given value is coherent or not
+ * regarding the policy you gave. You can just make a {@link SpreadsheetCell}
+ * call this method when its value has changed in order to react accordingly if
+ * the value is in error. (see example below).</li>
+ * </ul>
+ * <h3>Converter</h3> You will have to specify a converter for your type. It
+ * will handle all the conversion between your real value type (Double, Integer,
+ * LocalDate etc) and its string representation for the cell. <br>
+ * You can either use a pre-built {@link StringConverter} or our
+ * {@link StringConverterWithFormat}. This one just add one method (
+ * {@link StringConverterWithFormat#toStringFormat(Object, String)} which will
+ * convert your value with a String format (found in
+ * {@link SpreadsheetCell#getFormat()}).
+ * 
+ * <h3>Example</h3> You can create several types which are using the same
+ * editor. Suppose you want to handle Double values. You will implement the
+ * {@link #createEditor(SpreadsheetView)} method and use the
+ * {@link SpreadsheetCellEditor.DoubleEditor}. <br>
+ * 
+ * Then for each type you will provide your own policy in {@link #match(Object)}
+ * and in {@link #isError(Object)}, which most of the time will use your
+ * {@link #converter}. <br>
+ * 
+ * Here is an example of how to create a {@link StringConverterWithFormat} :
+ * 
+ * 
+ * 
+ * <pre>
+ * 
+ * StringConverterWithFormat specialConverter = new StringConverterWithFormat&lt;Double&gt;(new DoubleStringConverter()) {
+ *            &#64;Override
+ *             public String toString(Double item) {
+ *                  //We just redirect to the other method.
+ *                 return toStringFormat(item, "");
+ *             }
+ * 
+ *             &#64;Override
+ *             public String toStringFormat(Double item, String format) {
+ *                 if (item == null || Double.isNaN(item)) {
+ *                     return missingLabel; // For example return something else that an empty cell.
+ *                 } else{
+ *                     if (!("").equals(format) &amp;&amp; !Double.isNaN(item)) {
+ *                     //We format here the value
+ *                         return new DecimalFormat(format).format(item);
+ *                     } else {
+ *                     //We call the DoubleStringConverter that we gave in argument
+ *                         return myConverter.toString(item);
+ *                     }
+ *                 }
+ *             }
+ * 
+ *            &#64;Override
+ *             public Double fromString(String str) {
+ *                 if (str == null || str.isEmpty()) {
+ *                     return Double.NaN;
+ *                 } else {
+ *                     try {
+ *                         //Just returning the value
+ *                         Double myDouble = Double.parseDouble(str);
+ *                         return myDouble;
+ * 
+ *                     } catch (NumberFormatException e) {
+ *                         return myConverter.fromString(str);
+ *                     }
+ *                 }
+ *             }
+ *         }
+ * 
+ * </pre>
+ * 
+ * And then suppose you only want to accept double values between 0 and 100, and
+ * that a value superior to 10 is abnormal. <br>
+ * 
+ * <pre>
+ * &#064;Override
+ * public boolean isError(Object value) {
+ *     if (value instanceof Double) {
+ *         if ((Double) value &gt; 0 &amp;&amp; (Double) value &lt; 10) {
+ *             return false;
+ *         }
+ *         return true;
+ *     }
+ *     return true;
+ * }
+ * 
+ * &#064;Override
+ * public boolean match(Object value) {
+ *     if (value instanceof Double) {
+ *         return true;
+ *     } else {
+ *         try {
+ *             Double convertedValue = converter.fromString(value == null ? null : value.toString());
+ *             if (convertedValue &gt;= 0 &amp;&amp; convertedValue &lt;= 100)
+ *                 return true;
+ *             else
+ *                 return false;
+ *         } catch (Exception e) {
+ *             return false;
+ *         }
+ *     }
+ * }
+ * </pre>
+ * 
+ * @see SpreadsheetView
+ * @see SpreadsheetCellEditor
+ * @see SpreadsheetCell
+ */
+public abstract class SpreadsheetCellType<T> {
+    /** An instance of converter from string to cell type. */
+    protected StringConverter<T> converter;
+
+    /**
+     * Default constructor.
+     */
+    public SpreadsheetCellType() {
+
+    }
+
+    /**
+     * Constructor with the StringConverter directly provided.
+     * 
+     * @param converter
+     *            The converter to use
+     */
+    public SpreadsheetCellType(StringConverter<T> converter) {
+        this.converter = converter;
+    }
+
+    /**
+     * Creates an editor for this type of cells.
+     * 
+     * @param view
+     *            the spreadsheet that will own this editor
+     * @return the editor instance
+     */
+    public abstract SpreadsheetCellEditor createEditor(SpreadsheetView view);
+
+    /**
+     * Return a string representation of the given item for the
+     * {@link SpreadsheetView} to display using the inner
+     * {@link SpreadsheetCellType#converter} and the specified format.
+     * 
+     * @param object
+     * @param format
+     * @return a string representation of the given item.
+     */
+    public String toString(T object, String format) {
+        return toString(object);
+    }
+
+    /**
+     * Return a string representation of the given item for the
+     * {@link SpreadsheetView} to display using the inner
+     * {@link SpreadsheetCellType#converter}.
+     * 
+     * @param object
+     * @return a string representation of the given item.
+     */
+    public abstract String toString(T object);
+
+    /**
+     * Verify that the upcoming value can be set to the current cell. This is
+     * the first level of verification to prevent affecting a text to a double
+     * or a double to a date. For closer verification, use
+     * {@link #isError(Object)}.
+     * 
+     * @param value
+     *            the value to test
+     * @return true if it matches.
+     */
+    public abstract boolean match(Object value);
+
+    /**
+     * Returns true if the value is an error regarding the specification of its
+     * type.
+     * 
+     * @param value
+     * @return true if the value is an error.
+     */
+    public boolean isError(Object value) {
+        return false;
+    }
+
+    /**
+     *
+     * @return true if this SpreadsheetCellType accepts Objects to be dropped on
+     * the {@link SpreadsheetCell}. Currently only Files can be dropped. If
+     * accepted, prepare to receive them in {@link #match(java.lang.Object) }
+     * and {@link #convertValue(java.lang.Object) }.
+     */
+    public boolean acceptDrop() {
+        return false;
+    }
+    
+    /**
+     * This method will be called when a commit is happening.<br>
+     * This method will try to convert the value, be sure to call
+     * {@link #match(Object)} before to see if this method will succeed.
+     * 
+     * @param value
+     * @return null if not valid or the correct value otherwise.
+     */
+    public abstract T convertValue(Object value);
+
+    /**
+     * The {@link SpreadsheetCell} {@link Object} type instance.
+     */
+    public static final SpreadsheetCellType<Object> OBJECT = new ObjectType();
+
+    /**
+     * The {@link SpreadsheetCell} {@link Object} type base class.
+     */
+    public static class ObjectType extends SpreadsheetCellType<Object> {
+
+        public ObjectType() {
+            this(new StringConverterWithFormat<Object>() {
+                @Override
+                public Object fromString(String arg0) {
+                    return arg0;
+                }
+
+                @Override
+                public String toString(Object arg0) {
+                    return arg0 == null ? "" : arg0.toString(); //$NON-NLS-1$
+                }
+            });
+        }
+
+        public ObjectType(StringConverterWithFormat<Object> converter) {
+            super(converter);
+        }
+
+        @Override
+        public String toString() {
+            return "object"; //$NON-NLS-1$
+        }
+
+        @Override
+        public boolean match(Object value) {
+            return true;
+        }
+
+        /**
+        * Creates a cell that hold an Object at the specified position, with the
+        * specified row/column span.
+        * 
+        * @param row
+        *            row number
+        * @param column
+        *            column number
+        * @param rowSpan
+        *            rowSpan (1 is normal)
+        * @param columnSpan
+        *            ColumnSpan (1 is normal)
+        * @param value
+        *            the value to display
+        * @return a {@link SpreadsheetCell}
+        */
+        public SpreadsheetCell createCell(final int row, final int column, final int rowSpan, final int columnSpan,
+                final Object value) {
+            SpreadsheetCell cell = new SpreadsheetCellBase(row, column, rowSpan, columnSpan, this);
+            cell.setItem(value);
+            return cell;
+        }
+
+        @Override
+        public SpreadsheetCellEditor createEditor(SpreadsheetView view) {
+            return new SpreadsheetCellEditor.ObjectEditor(view);
+        }
+
+        @Override
+        public Object convertValue(Object value) {
+            return value;
+        }
+
+        @Override
+        public String toString(Object item) {
+            return converter.toString(item);
+        }
+
+    };
+
+    /**
+     * The {@link SpreadsheetCell} {@link String} type instance.
+     */
+    public static final StringType STRING = new StringType();
+
+    /**
+     * The {@link SpreadsheetCell} {@link String} type base class.
+     */
+    public static class StringType extends SpreadsheetCellType<String> {
+
+        public StringType() {
+            this(new DefaultStringConverter());
+        }
+
+        public StringType(StringConverter<String> converter) {
+            super(converter);
+        }
+
+        @Override
+        public String toString() {
+            return "string"; //$NON-NLS-1$
+        }
+
+        @Override
+        public boolean match(Object value) {
+            return true;
+        }
+
+        /**
+        * Creates a cell that hold a String at the specified position, with the
+        * specified row/column span.
+        * 
+        * @param row
+        *            row number
+        * @param column
+        *            column number
+        * @param rowSpan
+        *            rowSpan (1 is normal)
+        * @param columnSpan
+        *            ColumnSpan (1 is normal)
+        * @param value
+        *            the value to display
+        * @return a {@link SpreadsheetCell}
+        */
+        public SpreadsheetCell createCell(final int row, final int column, final int rowSpan, final int columnSpan,
+                final String value) {
+            SpreadsheetCell cell = new SpreadsheetCellBase(row, column, rowSpan, columnSpan, this);
+            cell.setItem(value);
+            return cell;
+        }
+
+        @Override
+        public SpreadsheetCellEditor createEditor(SpreadsheetView view) {
+            return new SpreadsheetCellEditor.StringEditor(view);
+        }
+
+        @Override
+        public String convertValue(Object value) {
+            String convertedValue = converter.fromString(value == null ? null : value.toString());
+            if (convertedValue == null || convertedValue.equals("")) { //$NON-NLS-1$
+                return null;
+            }
+            return convertedValue;
+        }
+
+        @Override
+        public String toString(String item) {
+            return converter.toString(item);
+        }
+
+    };
+
+    /**
+     * The {@link SpreadsheetCell} {@link Double} type instance.
+     */
+    public static final DoubleType DOUBLE = new DoubleType();
+
+    /**
+     * The {@link SpreadsheetCell} {@link Double} type base class.
+     */
+    public static class DoubleType extends SpreadsheetCellType<Double> {
+
+        public DoubleType() {
+
+            this(new StringConverterWithFormat<Double>(new DoubleStringConverter()) {
+                @Override
+                public String toString(Double item) {
+                    return toStringFormat(item, ""); //$NON-NLS-1$
+                }
+
+                @Override
+                public Double fromString(String str) {
+                    if (str == null || str.isEmpty() || "NaN".equals(str)) { //$NON-NLS-1$
+                        return Double.NaN;
+                    } else {
+                        return myConverter.fromString(str);
+                    }
+                }
+
+                @Override
+                public String toStringFormat(Double item, String format) {
+                    try {
+                        if (item == null || Double.isNaN(item)) {
+                            return ""; //$NON-NLS-1$
+                        } else {
+                            return new DecimalFormat(format).format(item);
+                        }
+                    } catch (Exception ex) {
+                        return myConverter.toString(item);
+                    }
+                }
+            });
+        }
+
+        public DoubleType(StringConverter<Double> converter) {
+            super(converter);
+        }
+
+        @Override
+        public String toString() {
+            return "double"; //$NON-NLS-1$
+        }
+
+        /**
+        * Creates a cell that hold a Double at the specified position, with the
+        * specified row/column span.
+        * 
+        * @param row
+        *            row number
+        * @param column
+        *            column number
+        * @param rowSpan
+        *            rowSpan (1 is normal)
+        * @param columnSpan
+        *            ColumnSpan (1 is normal)
+        * @param value
+        *            the value to display
+        * @return a {@link SpreadsheetCell}
+        */
+        public SpreadsheetCell createCell(final int row, final int column, final int rowSpan, final int columnSpan,
+                final Double value) {
+            SpreadsheetCell cell = new SpreadsheetCellBase(row, column, rowSpan, columnSpan, this);
+            cell.setItem(value);
+            return cell;
+        }
+
+        @Override
+        public SpreadsheetCellEditor createEditor(SpreadsheetView view) {
+            return new SpreadsheetCellEditor.DoubleEditor(view);
+        }
+
+        @Override
+        public boolean match(Object value) {
+            if (value instanceof Double)
+                return true;
+            else {
+                try {
+                    converter.fromString(value == null ? null : value.toString());
+                    return true;
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+        }
+
+        @Override
+        public Double convertValue(Object value) {
+            if (value instanceof Double)
+                return (Double) value;
+            else {
+                try {
+                    return converter.fromString(value == null ? null : value.toString());
+                } catch (Exception e) {
+                    return null;
+                }
+            }
+        }
+
+        @Override
+        public String toString(Double item) {
+            return converter.toString(item);
+        }
+
+        @Override
+        public String toString(Double item, String format) {
+            return ((StringConverterWithFormat<Double>) converter).toStringFormat(item, format);
+        }
+    };
+
+    /**
+     * The {@link SpreadsheetCell} {@link Integer} type instance.
+     */
+    public static final IntegerType INTEGER = new IntegerType();
+
+    /**
+     * The {@link SpreadsheetCell} {@link Integer} type base class.
+     */
+    public static class IntegerType extends SpreadsheetCellType<Integer> {
+
+        public IntegerType() {
+            this(new IntegerStringConverter() {
+                @Override
+                public String toString(Integer item) {
+                    if (item == null || Double.isNaN(item)) {
+                        return ""; //$NON-NLS-1$
+                    } else {
+                        return super.toString(item);
+                    }
+                }
+
+                @Override
+                public Integer fromString(String str) {
+                    if (str == null || str.isEmpty() || "NaN".equals(str)) { //$NON-NLS-1$
+                        return null;
+                    } else {
+                        // We try to integrate Double if possible by truncating
+                        // them
+                        try {
+                            Double temp = Double.parseDouble(str);
+                            return temp.intValue();
+                        } catch (Exception e) {
+                            return super.fromString(str);
+                        }
+                    }
+                }
+            });
+        }
+
+        public IntegerType(IntegerStringConverter converter) {
+            super(converter);
+        }
+
+        @Override
+        public String toString() {
+            return "Integer"; //$NON-NLS-1$
+        }
+
+        /**
+        * Creates a cell that hold a Integer at the specified position, with the
+        * specified row/column span.
+        * 
+        * @param row
+        *            row number
+        * @param column
+        *            column number
+        * @param rowSpan
+        *            rowSpan (1 is normal)
+        * @param columnSpan
+        *            ColumnSpan (1 is normal)
+        * @param value
+        *            the value to display
+        * @return a {@link SpreadsheetCell}
+        */
+        public SpreadsheetCell createCell(final int row, final int column, final int rowSpan, final int columnSpan,
+                final Integer value) {
+            SpreadsheetCell cell = new SpreadsheetCellBase(row, column, rowSpan, columnSpan, this);
+            cell.setItem(value);
+            return cell;
+        }
+
+        @Override
+        public SpreadsheetCellEditor createEditor(SpreadsheetView view) {
+            return new SpreadsheetCellEditor.IntegerEditor(view);
+        }
+
+        @Override
+        public boolean match(Object value) {
+            if (value instanceof Integer)
+                return true;
+            else {
+                try {
+                    converter.fromString(value == null ? null : value.toString());
+                    return true;
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+        }
+
+        @Override
+        public Integer convertValue(Object value) {
+            if (value instanceof Integer)
+                return (Integer) value;
+            else {
+                try {
+                    return converter.fromString(value == null ? null : value.toString());
+                } catch (Exception e) {
+                    return null;
+                }
+            }
+        }
+
+        @Override
+        public String toString(Integer item) {
+            return converter.toString(item);
+        }
+    };
+
+    /**
+     * Creates a {@link ListType}.
+     * 
+     * @param items
+     *            the list items
+     * @return the instance
+     */
+    public static final ListType LIST(final List<String> items) {
+        return new ListType(items);
+    }
+
+    /**
+     * The {@link SpreadsheetCell} {@link List} type base class.
+     */
+    public static class ListType extends SpreadsheetCellType<String> {
+        protected final List<String> items;
+
+        public ListType(final List<String> items) {
+            super(new DefaultStringConverter() {
+                @Override
+                public String fromString(String str) {
+                    if (str != null && items.contains(str)) {
+                        return str;
+                    } else {
+                        return null;
+                    }
+                }
+
+            });
+            this.items = items;
+        }
+
+        @Override
+        public String toString() {
+            return "list"; //$NON-NLS-1$
+        }
+
+        /**
+        * Creates a cell that hold a String at the specified position, with the
+        * specified row/column span.
+        * 
+        * @param row
+        *            row number
+        * @param column
+        *            column number
+        * @param rowSpan
+        *            rowSpan (1 is normal)
+        * @param columnSpan
+        *            ColumnSpan (1 is normal)
+        * @param value
+        *            the value to display
+        * @return a {@link SpreadsheetCell}
+        */
+        public SpreadsheetCell createCell(final int row, final int column, final int rowSpan, final int columnSpan,
+                String value) {
+            SpreadsheetCell cell = new SpreadsheetCellBase(row, column, rowSpan, columnSpan, this);
+            if (items != null && items.size() > 0) {
+                if (value != null && items.contains(value)) {
+                    cell.setItem(value);
+                } else {
+                    cell.setItem(items.get(0));
+                }
+            }
+            return cell;
+        }
+
+        @Override
+        public SpreadsheetCellEditor createEditor(SpreadsheetView view) {
+            return new SpreadsheetCellEditor.ListEditor<>(view, items);
+        }
+
+        @Override
+        public boolean match(Object value) {
+            if (value instanceof String && items.contains(value.toString()))
+                return true;
+            else
+                return items.contains(value == null ? null : value.toString());
+        }
+
+        @Override
+        public String convertValue(Object value) {
+            return converter.fromString(value == null ? null : value.toString());
+        }
+
+        @Override
+        public String toString(String item) {
+            return converter.toString(item);
+        }
+    }
+
+    /**
+     * The {@link SpreadsheetCell} {@link LocalDate} type instance.
+     */
+    public static final DateType DATE = new DateType();
+
+    /**
+     * The {@link SpreadsheetCell} {@link LocalDate} type base class.
+     */
+    public static class DateType extends SpreadsheetCellType<LocalDate> {
+
+        /**
+         * Creates a new DateType.
+         */
+        public DateType() {
+            this(new StringConverterWithFormat<LocalDate>() {
+                @Override
+                public String toString(LocalDate item) {
+                    return toStringFormat(item, ""); //$NON-NLS-1$
+                }
+
+                @Override
+                public LocalDate fromString(String str) {
+                    try {
+                        return LocalDate.parse(str);
+                    } catch (Exception e) {
+                        return null;
+                    }
+                }
+
+                @Override
+                public String toStringFormat(LocalDate item, String format) {
+                    if (("").equals(format) && item != null) { //$NON-NLS-1$
+                        return item.toString();
+                    } else if (item != null) {
+                        return item.format(DateTimeFormatter.ofPattern(format));
+                    } else {
+                        return ""; //$NON-NLS-1$
+                    }
+                }
+            });
+        }
+
+        public DateType(StringConverter<LocalDate> converter) {
+            super(converter);
+        }
+
+        @Override
+        public String toString() {
+            return "date"; //$NON-NLS-1$
+        }
+
+        /**
+        * Creates a cell that hold a LocalDate at the specified position, with the
+        * specified row/column span.
+        * 
+        * @param row
+        *            row number
+        * @param column
+        *            column number
+        * @param rowSpan
+        *            rowSpan (1 is normal)
+        * @param columnSpan
+        *            ColumnSpan (1 is normal)
+        * @param value
+        *            the value to display
+        * @return a {@link SpreadsheetCell}
+        */
+        public SpreadsheetCell createCell(final int row, final int column, final int rowSpan, final int columnSpan,
+                final LocalDate value) {
+            SpreadsheetCell cell = new SpreadsheetCellBase(row, column, rowSpan, columnSpan, this);
+            cell.setItem(value);
+            return cell;
+        }
+
+        @Override
+        public SpreadsheetCellEditor createEditor(SpreadsheetView view) {
+            return new SpreadsheetCellEditor.DateEditor(view, converter);
+        }
+
+        @Override
+        public boolean match(Object value) {
+            if (value instanceof LocalDate)
+                return true;
+            else {
+                try {
+                    LocalDate temp = converter.fromString(value == null ? null : value.toString());
+                    return temp != null;
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+        }
+
+        @Override
+        public LocalDate convertValue(Object value) {
+            if (value instanceof LocalDate)
+                return (LocalDate) value;
+            else {
+                try {
+                    return converter.fromString(value == null ? null : value.toString());
+                } catch (Exception e) {
+                    return null;
+                }
+            }
+        }
+
+        @Override
+        public String toString(LocalDate item) {
+            return converter.toString(item);
+        }
+
+        @Override
+        public String toString(LocalDate item, String format) {
+            return ((StringConverterWithFormat<LocalDate>) converter).toStringFormat(item, format);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/spreadsheet/SpreadsheetColumn.java b/src/org/controlsfx/control/spreadsheet/SpreadsheetColumn.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf45a1ed686c7d6bed4b0a08b861beef77b91664
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/SpreadsheetColumn.java
@@ -0,0 +1,372 @@
+/**
+ * Copyright (c) 2013, 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import static impl.org.controlsfx.i18n.Localization.asKey;
+import static impl.org.controlsfx.i18n.Localization.localize;
+import impl.org.controlsfx.spreadsheet.CellView;
+import java.util.List;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ReadOnlyDoubleProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.TableColumn;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.stage.WindowEvent;
+import org.controlsfx.tools.Utils;
+
+/**
+ * A {@link SpreadsheetView} is made up of a number of {@link SpreadsheetColumn}
+ * instances.
+ * 
+ * <h3>Configuration</h3> SpreadsheetColumns are instantiated by the
+ * {@link SpreadsheetView} itself, so there is no public constructor for this
+ * class. To access the available columns, you need to call
+ * {@link SpreadsheetView#getColumns()}.
+ * 
+ * <p>
+ * SpreadsheetColumn gives you the ability to modify some aspects of the column,
+ * for example the {@link #setPrefWidth(double) width} or
+ * {@link #setResizable(boolean) resizability} of the column.
+ * 
+ * <p>
+ * You have the ability to fix this column at the left of the SpreadsheetView by
+ * calling {@link #setFixed(boolean)}. But you are strongly advised to check if
+ * it is possible with {@link #isColumnFixable()} before calling
+ * {@link #setFixed(boolean)}. Take a look at the {@link SpreadsheetView}
+ * description to understand the fixing constraints.
+ * 
+ * <p>
+ * If the column can be fixed, a {@link ContextMenu} will appear if the user right-clicks on it. 
+ * If not, nothing will appear and the user will not have the possibility to fix it.
+ * 
+ * <h3>Screenshot</h3>
+ * The column <b>A</b> is fixed and is covering column <b>B</b> and partially
+ * column <b>C</b>. The context menu is being shown and offers the possibility
+ * to unfix the column.
+ * 
+ * <br>
+ * <br>
+ * <center><img src="fixedColumn.png" alt="Screenshot of SpreadsheetColumn"></center>
+ * 
+ * @see SpreadsheetView
+ */
+public final class SpreadsheetColumn {
+
+    /***************************************************************************
+     * * Private Fields * *
+     **************************************************************************/
+    private final SpreadsheetView spreadsheetView;
+    final TableColumn<ObservableList<SpreadsheetCell>, SpreadsheetCell> column;
+    private final boolean canFix;
+    private final Integer indexColumn;
+    private MenuItem fixItem;
+
+    /***************************************************************************
+     * * Constructor * *
+     **************************************************************************/
+    /**
+     * Creates a new SpreadsheetColumn.
+     * 
+     * @param column
+     * @param spreadsheetView
+     * @param indexColumn
+     */
+    SpreadsheetColumn(final TableColumn<ObservableList<SpreadsheetCell>, SpreadsheetCell> column,
+            final SpreadsheetView spreadsheetView, final Integer indexColumn, Grid grid) {
+        this.spreadsheetView = spreadsheetView;
+        this.column = column;
+        column.setMinWidth(0);
+        this.indexColumn = indexColumn;
+        canFix = initCanFix(grid);
+
+        // The contextMenu creation must be on the JFX thread
+        CellView.getValue(() -> {
+            column.setContextMenu(getColumnContextMenu());
+        });
+
+        // When changing frozen fixed columns, we need to update the ContextMenu.
+        spreadsheetView.fixingColumnsAllowedProperty().addListener(new ChangeListener<Boolean>() {
+
+            @Override
+            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+                CellView.getValue(() -> {
+                    column.setContextMenu(getColumnContextMenu());
+                });
+            }
+        });
+
+        // When ColumnsHeaders are changing, we update the text
+        grid.getColumnHeaders().addListener(new InvalidationListener() {
+            @Override
+            public void invalidated(Observable arg0) {
+                List<String> columnsHeader = spreadsheetView.getGrid().getColumnHeaders();
+                if (columnsHeader.size() <= indexColumn) {
+                    setText(Utils.getExcelLetterFromNumber(indexColumn));
+                } else if (!columnsHeader.get(indexColumn).equals(getText())) {
+                    setText(columnsHeader.get(indexColumn));
+                }
+            }
+        });
+
+        // When changing rows, we re-calculate if this columns can be fixed.
+        grid.getRows().addListener(new InvalidationListener() {
+            @Override
+            public void invalidated(Observable arg0) {
+                initCanFix(grid);
+            }
+        });
+    }
+
+    /***************************************************************************
+     * * Public Methods * *
+     **************************************************************************/
+
+    /**
+     * Return whether this column is fixed or not.
+     * 
+     * @return true if this column is fixed.
+     */
+    public boolean isFixed() {
+        return spreadsheetView.getFixedColumns().contains(this);
+    }
+
+    /**
+     * Fix this column to the left if possible, although it is recommended that
+     * you call {@link #isColumnFixable()} before trying to fix a column.
+     *
+     * If you want to fix several columns (because of a span for example), add
+     * all the columns directly in {@link SpreadsheetView#getFixedColumns() }.
+     * Always use {@link SpreadsheetView#areSpreadsheetColumnsFixable(java.util.List)
+     * } before.
+     *
+     * @param fixed
+     */
+    public void setFixed(boolean fixed) {
+        if (fixed) {
+            spreadsheetView.getFixedColumns().add(this);
+        } else {
+            spreadsheetView.getFixedColumns().removeAll(this);
+        }
+    }
+
+    /**
+     * Set the width of this column.
+     * 
+     * @param width
+     */
+    public void setPrefWidth(double width) {
+        width = Math.ceil(width);
+        if (column.getPrefWidth() == width && column.getWidth() != width) {
+            column.impl_setWidth(width);
+        } else {
+            column.setPrefWidth(width);
+        }
+        spreadsheetView.columnWidthSet(indexColumn);
+    }
+
+    /**
+     * Return the actual width of the column.
+     *
+     * @return the actual width of the column
+     */
+    public double getWidth() {
+        return column.getWidth();
+    }
+
+    /**
+     * Return the Property related to the actual width of the column.
+     *
+     * @return
+     */
+    public final ReadOnlyDoubleProperty widthProperty() {
+        return column.widthProperty();
+    }
+
+    /**
+     * Set the minimum width for this SpreadsheetColumn.
+     *
+     * @param value
+     */
+    public final void setMinWidth(double value) {
+        column.setMinWidth(value);
+    }
+
+    /**
+     * Return the minimum width for this SpreadsheetColumn.
+     *
+     * @return
+     */
+    public final double getMinWidth() {
+        return column.getMinWidth();
+    }
+
+    /**
+     * Return the Property related to the minimum width of this
+     * SpreadsheetColumn.
+     *
+     * @return
+     */
+    public final DoubleProperty minWidthProperty() {
+        return column.minWidthProperty();
+    }
+
+    /**
+     * Return the Property related to the maximum width of this
+     * SpreadsheetColumn.
+     *
+     * @return
+     */
+    public final DoubleProperty maxWidthProperty() {
+        return column.maxWidthProperty();
+    }
+
+    /**
+     * Set the maximum width for this SpreadsheetColumn.
+     *
+     * @param value
+     */
+    public final void setMaxWidth(double value) {
+        column.setMaxWidth(value);
+    }
+
+    /**
+     * Return the maximum width for this SpreadsheetColumn.
+     *
+     * @return
+     */
+    public final double getMaxWidth() {
+        return column.getMaxWidth();
+    }
+    /**
+     * If this column can be resized by the user
+     * 
+     * @param b
+     */
+    public void setResizable(boolean b) {
+        column.setResizable(b);
+    }
+
+    /**
+     * If the column is resizable, it will compute the optimum width for all the
+     * visible cells to be visible.
+     */
+    public void fitColumn() {
+        if (column.isResizable() && spreadsheetView.getCellsViewSkin() != null) {
+            spreadsheetView.getCellsViewSkin().resize(column, 100);
+        }
+    }
+
+    /**
+     * Indicate whether this column can be fixed or not. Call that method before
+     * calling {@link #setFixed(boolean)} or adding an item to
+     * {@link SpreadsheetView#getFixedColumns()}.
+     *
+     * A column cannot be fixed alone if any cell inside the column has a column
+     * span superior to one.
+     *
+     * @return true if this column is fixable.
+     */
+    public boolean isColumnFixable() {
+        return canFix && spreadsheetView.isFixingColumnsAllowed();
+    }
+
+    /***************************************************************************
+     * * Private Methods * *
+     **************************************************************************/
+    private void setText(String text) {
+        column.setText(text);
+    }
+
+    private String getText() {
+        return column.getText();
+    }
+
+    /**
+     * Generate a context Menu in order to fix/unfix some column It is shown
+     * when right-clicking on the column header
+     * 
+     * @return a context menu.
+     */
+    private ContextMenu getColumnContextMenu() {
+        if (isColumnFixable()) {
+            final ContextMenu contextMenu = new ContextMenu();
+
+            this.fixItem = new MenuItem(localize(asKey("spreadsheet.column.menu.fix"))); //$NON-NLS-1$
+            contextMenu.setOnShowing(new EventHandler<WindowEvent>() {
+
+                @Override
+                public void handle(WindowEvent event) {
+                    if (!isFixed()) {
+                        fixItem.setText(localize(asKey("spreadsheet.column.menu.fix"))); //$NON-NLS-1$
+                    } else {
+                        fixItem.setText(localize(asKey("spreadsheet.column.menu.unfix"))); //$NON-NLS-1$
+                }
+                }
+            });
+            fixItem.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("pinSpreadsheetView.png")))); //$NON-NLS-1$
+            fixItem.setOnAction(new EventHandler<ActionEvent>() {
+                @Override
+                public void handle(ActionEvent arg0) {
+                    if (!isFixed()) {
+                        setFixed(true);
+                    } else {
+                        setFixed(false);
+                    }
+                }
+            });
+            contextMenu.getItems().addAll(fixItem);
+
+            return contextMenu;
+        } else {
+            return new ContextMenu();
+        }
+    }
+
+    /**
+     * Verify that you can fix this column. 
+     * 
+     * @return if it's fixable.
+     */
+    private boolean initCanFix(Grid grid) {
+        for (ObservableList<SpreadsheetCell> row : grid.getRows()) {
+            int columnSpan = row.get(indexColumn).getColumnSpan();
+            if (columnSpan > 1) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/src/org/controlsfx/control/spreadsheet/SpreadsheetView.java b/src/org/controlsfx/control/spreadsheet/SpreadsheetView.java
new file mode 100644
index 0000000000000000000000000000000000000000..fef76586165609cde6644391d22e0cd27d2dafd1
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/SpreadsheetView.java
@@ -0,0 +1,1928 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import static impl.org.controlsfx.i18n.Localization.asKey;
+import static impl.org.controlsfx.i18n.Localization.localize;
+import impl.org.controlsfx.spreadsheet.CellView;
+import impl.org.controlsfx.spreadsheet.FocusModelListener;
+import impl.org.controlsfx.spreadsheet.GridViewSkin;
+import impl.org.controlsfx.spreadsheet.RectangleSelection.GridRange;
+import impl.org.controlsfx.spreadsheet.RectangleSelection.SelectionRange;
+import impl.org.controlsfx.spreadsheet.SpreadsheetGridView;
+import impl.org.controlsfx.spreadsheet.SpreadsheetHandle;
+import impl.org.controlsfx.spreadsheet.TableViewSpanSelectionModel;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javafx.application.Platform;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyBooleanProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.ReadOnlyObjectWrapper;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.beans.value.WeakChangeListener;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.collections.ObservableMap;
+import javafx.event.ActionEvent;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.event.EventType;
+import javafx.event.WeakEventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.Control;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.ScrollBar;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.Skin;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableView;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.Clipboard;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.DataFormat;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination;
+import javafx.scene.input.KeyEvent;
+import javafx.stage.WindowEvent;
+import javafx.util.Pair;
+
+import org.controlsfx.control.PropertySheet.Item;
+import org.controlsfx.tools.Utils;
+
+/**
+ * The SpreadsheetView is a control similar to the JavaFX {@link TableView}
+ * control but with different functionalities and use cases. The aim is to have
+ * a powerful grid where data can be written and retrieved.
+ * 
+ * <h3>Features</h3>
+ * <ul>
+ * <li>Cells can span in row and in column.</li>
+ * <li>Rows can be fixed to the top of the {@link SpreadsheetView} so that they
+ * are always visible on screen.</li>
+ * <li>Columns can be fixed to the left of the {@link SpreadsheetView} so that
+ * they are always visible on screen.</li>
+ * <li>A row header can be switched on in order to display the row number.</li>
+ * <li>Rows can be resized just like columns with click &amp; drag.</li>
+ * <li>Both row and column header can be visible or invisible.</li>
+ * <li>Selection of several cells can be made with a click and drag.</li>
+ * <li>A copy/paste context menu is accessible with a right-click. The usual
+ * shortcuts are also working.</li>
+ * <li>{@link Picker} can be placed above column header or to the side of the
+ * row header.</li>
+ * </ul>
+ * 
+ * <br>
+ * 
+ * <h3>Fixing Rows and Columns</h3> 
+ * <br>
+ * You can fix some rows and some columns by right-clicking on their header. A
+ * context menu will appear if it's possible to fix them. When fixed, the label
+ * header will then be in italic and the background will turn to dark grey.
+ * <br>
+ * You have also the possibility to fix them manually by adding and removing
+ * items from {@link #getFixedRows()} and {@link #getFixedColumns()}. But you
+ * are strongly advised to check if it's possible to do so with
+ * {@link SpreadsheetColumn#isColumnFixable()} for the fixed columns and with
+ * {@link #isRowFixable(int)} for the fixed rows.
+ * <br>
+ *
+ * A set of rows cannot be fixed if any cell inside these rows has a row span
+ * superior to the number of fixed rows. Likewise, a set of columns cannot be
+ * fixed if any cell inside these columns has a column span superior to the
+ * number of fixed columns.
+ * 
+ * <br><br>
+ * If you want to fix several rows or columns together, and they have a span
+ * inside, you can call {@link #areRowsFixable(java.util.List) } or  {@link #areSpreadsheetColumnsFixable(java.util.List)
+ * }
+ * to verify if you can fix them. Be sure to add them all in once otherwise the
+ * system will detect that a span is going out of bounds and will throw an
+ * exception.
+ *
+ * Calling those methods prior
+ * every move will ensure that no exception will be thrown.
+ * <br><br>
+ * You have also the possibility to deactivate these possibilities. For example,
+ * you force some row/column to be fixed and then the user cannot change the 
+ * settings. 
+ * <br>
+ * 
+ * <h3>Headers</h3>
+ * <br>
+ * You can also access and toggle header's visibility by using the methods
+ * provided like {@link #setShowRowHeader(boolean) } or {@link #setShowColumnHeader(boolean)
+ * }.
+ * 
+ * <br>
+ * Users can double-click on a column header will resize the column to the best
+ * size in order to fully see each cell in it. Same rule apply for row header.
+ * Also note that double-clicking on the little space between two row or two
+ * columns (when resizable) will also work just like Excel.
+ * 
+ * <h3>Pickers</h3>
+ * <br>
+ * 
+ * You can show some little images next to the headers. They will appear on the 
+ * left of the VerticalHeader and on top on the HorizontalHeader. They are called
+ * "picker" because they were used originally for picking a row or a column to 
+ * insert in the SpreadsheetView.
+ * <br>
+ * But you can do anything you want with it. Simply put a row or a column index
+ * in {@link #getRowPickers() } and {@link #getColumnPickers() } along with an
+ * instance of {@link Picker}. You can override the {@link Picker#onClick() }
+ * method in order to react when the user click on the picker.
+ * <br>
+ * The pickers will appear on the top of the column's header and on the left of 
+ * the row's header.
+ * <br>
+ * 
+ * <h3>Copy pasting</h3> You can copy any cell you want and paste it elsewhere.
+ * Be aware that only the value inside will be pasted, not the style nor the
+ * type. Thus the value you're trying to paste must be compatible with the
+ * {@link SpreadsheetCellType} of the receiving cell. Pasting a Double into a
+ * String will work but the reverse operation will not. 
+ * <br>
+ * See {@link SpreadsheetCellType} <i>Value Verification</i> documentation for more 
+ * information.
+ * <br>
+ * A unique cell or a selection can be copied and pasted.
+ * 
+ * <br>
+ * <br>
+ * <h3>Code Samples</h3> Just like the {@link TableView}, you instantiate the
+ * underlying model, a {@link Grid}. You will create some rows filled with {@link SpreadsheetCell}.
+ * 
+ * <br>
+ * <br>
+ * 
+ * <pre>
+ * int rowCount = 15;
+ *     int columnCount = 10;
+ *     GridBase grid = new GridBase(rowCount, columnCount);
+ *     
+ *     ObservableList&lt;ObservableList&lt;SpreadsheetCell&gt;&gt; rows = FXCollections.observableArrayList();
+ *     for (int row = 0; row &lt; grid.getRowCount(); ++row) {
+ *         final ObservableList&lt;SpreadsheetCell&gt; list = FXCollections.observableArrayList();
+ *         for (int column = 0; column &lt; grid.getColumnCount(); ++column) {
+ *             list.add(SpreadsheetCellType.STRING.createCell(row, column, 1, 1,"value"));
+ *         }
+ *         rows.add(list);
+ *     }
+ *     grid.setRows(rows);
+ *
+ *     SpreadsheetView spv = new SpreadsheetView(grid);
+ *     
+ * </pre>
+ * 
+ * At that moment you can span some of the cells with the convenient method
+ * provided by the grid. Then you just need to instantiate the SpreadsheetView. <br>
+ * <h3>Visual:</h3> <center><img src="spreadsheetView.png" alt="Screenshot of SpreadsheetView"></center>
+ * 
+ * @see SpreadsheetCell
+ * @see SpreadsheetCellBase
+ * @see SpreadsheetColumn
+ * @see Grid
+ * @see GridBase
+ * @see Picker
+ */
+public class SpreadsheetView extends Control{
+
+    /***************************************************************************
+     * * Static Fields * *
+     **************************************************************************/
+
+    /**
+     * The SpanType describes in which state each cell can be. When a spanning
+     * is occurring, one cell is becoming larger and the others are becoming
+     * invisible. Thus, that particular cell is masking the others. <br>
+     * <br>
+     * But the SpanType cannot be known in advance because it's evolving for
+     * each cell during the lifetime of the {@link SpreadsheetView}. Suppose you
+     * have a cell spanning in row, the first one is in a ROW_VISIBLE state, and
+     * all the other below are in a ROW_SPAN_INVISIBLE state. But if the user is
+     * scrolling down, the first will go out of sight. At that moment, the
+     * second cell is switching from ROW_SPAN_INVISIBLE state to ROW_VISIBLE
+     * state. <br>
+     * <br>
+     * 
+     * <center><img src="spanType.png" alt="Screenshot of SpreadsheetView.SpanType"></center>
+     * Refer to {@link SpreadsheetView} for more information.
+     */
+    public static enum SpanType {
+
+        /**
+         * Visible cell, can be a unique cell (no span) or the first one inside
+         * a column spanning cell.
+         */
+        NORMAL_CELL,
+
+        /**
+         * Invisible cell because a cell in a NORMAL_CELL state on the left is
+         * covering it.
+         */
+        COLUMN_SPAN_INVISIBLE,
+
+        /**
+         * Invisible cell because a cell in a ROW_VISIBLE state on the top is
+         * covering it.
+         */
+        ROW_SPAN_INVISIBLE,
+
+        /** Visible Cell but has some cells below in a ROW_SPAN_INVISIBLE state. */
+        ROW_VISIBLE,
+
+        /**
+         * Invisible cell situated in diagonal of a cell in a ROW_VISIBLE state.
+         */
+        BOTH_INVISIBLE;
+    }
+
+    /**
+     * Default width of the VerticalHeader.
+     */
+    private static final double DEFAULT_ROW_HEADER_WIDTH = 30.0;
+    /***************************************************************************
+     * * Private Fields * *
+     **************************************************************************/
+
+    protected final SpreadsheetGridView cellsView;// The main cell container.
+    private SimpleObjectProperty<Grid> gridProperty = new SimpleObjectProperty<>();
+    private DataFormat fmt;
+    
+    private final ObservableList<Integer> fixedRows = FXCollections.observableArrayList();
+    private final ObservableList<SpreadsheetColumn> fixedColumns = FXCollections.observableArrayList();
+
+    private final BooleanProperty fixingRowsAllowedProperty = new SimpleBooleanProperty(true);
+    private final BooleanProperty fixingColumnsAllowedProperty = new SimpleBooleanProperty(true);
+
+    private final BooleanProperty showColumnHeader = new SimpleBooleanProperty(true, "showColumnHeader", true); //$NON-NLS-1$
+    private final BooleanProperty showRowHeader = new SimpleBooleanProperty(true, "showRowHeader", true); //$NON-NLS-1$
+
+    private BitSet rowFix; // Compute if we can fix the rows or not.
+
+    private final ObservableMap<Integer, Picker> rowPickers = FXCollections.observableHashMap();
+
+    private final ObservableMap<Integer, Picker> columnPickers = FXCollections.observableHashMap();
+
+    // Properties needed by the SpreadsheetView and managed by the skin (source
+    // is the VirtualFlow)
+    private ObservableList<SpreadsheetColumn> columns = FXCollections.observableArrayList();
+    private Map<SpreadsheetCellType<?>, SpreadsheetCellEditor> editors = new IdentityHashMap<>();
+    private final SpreadsheetViewSelectionModel selectionModel;
+    
+    /**
+     * The vertical header width, just for the Label, not the Pickers.
+     */
+    private final DoubleProperty rowHeaderWidth = new SimpleDoubleProperty(DEFAULT_ROW_HEADER_WIDTH);
+
+    /**
+     * Since the default with applied to TableColumn is 80. If a user sets a
+     * width of 80, the column will be detected as having the default with and
+     * therefore will be requested to be autosized. In order to prevent that, we
+     * must detect which columns has been specifically set and which not. With
+     * that BitSet, we are able to make the difference between a "default" 80
+     * width applied by the system, and a 80 width applid by a user.
+     */
+    private final BitSet columnWidthSet = new BitSet();
+    // The handle that bridges with implementation.
+    final SpreadsheetHandle handle = new SpreadsheetHandle() {
+        
+        @Override
+        protected SpreadsheetView getView() {
+            return SpreadsheetView.this;
+        }
+
+        @Override
+        protected GridViewSkin getCellsViewSkin() {
+            return SpreadsheetView.this.getCellsViewSkin();
+        }
+
+        @Override
+        protected SpreadsheetGridView getGridView() {
+            return SpreadsheetView.this.getCellsView();
+        }
+
+        @Override
+        protected boolean isColumnWidthSet(int indexColumn) {
+            return columnWidthSet.get(indexColumn);
+        }
+    };
+
+    /**
+     * @return the inner table view skin
+     */
+    public final GridViewSkin getCellsViewSkin() {
+        return (GridViewSkin) (cellsView.getSkin());
+    }
+
+    /**
+     * @return the inner table view
+     */
+    final SpreadsheetGridView getCellsView() {
+        return cellsView;
+    }
+    
+    /**
+     * Used by {@link SpreadsheetColumn} internally in order to specify if a
+     * column width has been set by the user.
+     *
+     * @param indexColumn
+     */
+    void columnWidthSet(int indexColumn) {
+        columnWidthSet.set(indexColumn);
+    }
+
+    /***************************************************************************
+     * * Constructor * *
+     **************************************************************************/
+
+    /**
+     * This constructor will generate sample Grid with 100 rows and 15 columns.
+     * All cells are typed as String (see {@link SpreadsheetCellType#STRING}).
+     */
+    public SpreadsheetView(){
+        this(getSampleGrid());
+        for(SpreadsheetColumn column: getColumns()){
+            column.setPrefWidth(100);
+        }
+    }
+    
+    /**
+     * Creates a SpreadsheetView control with the {@link Grid} specified.
+     *
+     * @param grid The Grid that contains the items to be rendered
+     */
+    public SpreadsheetView(final Grid grid) {
+        super();
+        //We want to recompute the rectangleHeight when a fixedRow is resized.
+        addEventHandler(RowHeightEvent.ROW_HEIGHT_CHANGE, (RowHeightEvent event) -> {
+            if(getFixedRows().contains(event.getRow()) && getCellsViewSkin() != null){
+                getCellsViewSkin().computeFixedRowHeight();
+            }
+        });
+        getStyleClass().add("SpreadsheetView"); //$NON-NLS-1$
+        // anonymous skin
+        setSkin(new Skin<SpreadsheetView>() {
+            @Override
+            public Node getNode() {
+                return SpreadsheetView.this.getCellsView();
+            }
+
+            @Override
+            public SpreadsheetView getSkinnable() {
+                return SpreadsheetView.this;
+            }
+
+            @Override
+            public void dispose() {
+                // no-op
+            }
+        });
+
+        this.cellsView = new SpreadsheetGridView(handle);
+        getChildren().add(cellsView);
+        
+        /**
+         * Add a listener to the selection model in order to edit the spanned
+         * cells when clicked
+         */
+        TableViewSpanSelectionModel tableViewSpanSelectionModel = new TableViewSpanSelectionModel(this,cellsView);
+        cellsView.setSelectionModel(tableViewSpanSelectionModel);
+        tableViewSpanSelectionModel.setCellSelectionEnabled(true);
+        tableViewSpanSelectionModel.setSelectionMode(SelectionMode.MULTIPLE);
+        selectionModel = new SpreadsheetViewSelectionModel(this, tableViewSpanSelectionModel);
+
+        /**
+         * Set the focus model to track keyboard change and redirect focus on
+         * spanned cells
+         */
+        // We add a listener on the focus model in order to catch when we are on
+        // a hidden cell
+        cellsView.getFocusModel().focusedCellProperty()
+                .addListener((ChangeListener<TablePosition>) (ChangeListener<?>) new FocusModelListener(this,cellsView));
+
+        /**
+         * Keyboard action, maybe use an accelerator
+         */
+        cellsView.setOnKeyPressed(keyPressedHandler);
+        
+        /**
+         * ContextMenu handling.
+         */
+        this.contextMenuProperty().addListener(new WeakChangeListener<>(contextMenuChangeListener));
+        // The contextMenu creation must be on the JFX thread
+        CellView.getValue(() -> {
+            setContextMenu(getSpreadsheetViewContextMenu());
+        });
+
+        setGrid(grid);
+        setEditable(true);
+        
+        // Listeners & handlers
+        fixedRows.addListener(fixedRowsListener);
+        fixedColumns.addListener(fixedColumnsListener);
+    }
+    /***************************************************************************
+     * * Public Methods * *
+     **************************************************************************/
+
+    /**
+     * Set a new Grid for the SpreadsheetView. This will be called by default by
+     * {@link #SpreadsheetView(Grid)}. So this is useful when you want to
+     * refresh your SpreadsheetView with a new model. This will keep the state
+     * of your SpreadsheetView (position of the bar, number of fixedRows etc).
+     * 
+     * @param grid the new Grid
+     */
+    public final void setGrid(Grid grid) {
+        if(grid == null){
+            return;
+        }
+        // Reactivate that after
+//        verifyGrid(grid);
+        gridProperty.set(grid);
+        initRowFix(grid);
+
+        /**
+         * We need to verify that the previous fixedRows are still compatible
+         * with our new model
+         */
+
+        List<Integer> newFixedRows = new ArrayList<>();
+        for (Integer rowFixed : getFixedRows()) {
+            if (isRowFixable(rowFixed)) {
+                newFixedRows.add(rowFixed);
+            }
+        }
+        getFixedRows().setAll(newFixedRows);
+
+        /**
+         * We need to store the index of the fixedColumns and clear then because
+         * we will keep reference to SpreadsheetColumn that no longer exist.
+         */
+        List<Integer> columnsFixed = new ArrayList<>();
+        for (SpreadsheetColumn column : getFixedColumns()) {
+            columnsFixed.add(getColumns().indexOf(column));
+        }
+        getFixedColumns().clear();
+
+        /**
+         * We try to save the width of the column as we save the height of our rows so that we preserve the state.
+         */
+        List<Double> widthColumns = new ArrayList<>();
+        for (SpreadsheetColumn column : columns) {
+            widthColumns.add(column.getWidth());
+        }
+        //We need to update the focused cell afterwards
+        Pair<Integer, Integer> focusedPair = null;
+        TablePosition focusedCell = cellsView.getFocusModel().getFocusedCell();
+        if (focusedCell != null && focusedCell.getRow() != -1 && focusedCell.getColumn() != -1) {
+            focusedPair = new Pair(focusedCell.getRow(), focusedCell.getColumn());
+        }
+
+        final Pair<Integer, Integer> finalPair = focusedPair;
+        
+        if (grid.getRows() != null) {
+            final ObservableList<ObservableList<SpreadsheetCell>> observableRows = FXCollections
+                    .observableArrayList(grid.getRows());
+            cellsView.getItems().clear();
+            cellsView.setItems(observableRows);
+
+            final int columnCount = grid.getColumnCount();
+            columns.clear();
+            for (int columnIndex = 0; columnIndex < columnCount; ++columnIndex) {
+                final SpreadsheetColumn spreadsheetColumn = new SpreadsheetColumn(getTableColumn(grid, columnIndex), this, columnIndex, grid);
+                if(widthColumns.size() > columnIndex){
+                    spreadsheetColumn.setPrefWidth(widthColumns.get(columnIndex));
+                }
+                columns.add(spreadsheetColumn);
+                // We verify if this column was fixed before and try to re-fix
+                // it.
+                if (columnsFixed.contains((Integer) columnIndex) && spreadsheetColumn.isColumnFixable()) {
+                    spreadsheetColumn.setFixed(true);
+                }
+            }
+        }
+        
+        List<Pair<Integer, Integer>> selectedCells = new ArrayList<>();
+        for (TablePosition position : getSelectionModel().getSelectedCells()) {
+            selectedCells.add(new Pair<>(position.getRow(), position.getColumn()));
+        }
+        
+        
+        /**
+         * Since the TableView is added to the sceneGraph, it's not possible to
+         * modify the columns in another thread. We normally should call
+         * Platform.runLater() and exit. But in this particular case, we need to
+         * add the tableColumn right now. So that when we exit this "setGrid"
+         * method, we are sure we can manipulate all the elements.
+         *
+         * We also try to be smart here when we already have some columns in
+         * order to re-use them and minimize the time used to add/remove
+         * columns.
+         */
+        Runnable runnable = () -> {
+            if (cellsView.getColumns().size() > grid.getColumnCount()) {
+                cellsView.getColumns().remove(grid.getColumnCount(), cellsView.getColumns().size());
+            } else if (cellsView.getColumns().size() < grid.getColumnCount()) {
+                for (int i = cellsView.getColumns().size(); i < grid.getColumnCount(); ++i) {
+                    cellsView.getColumns().add(columns.get(i).column);
+                }
+            }
+            ((TableViewSpanSelectionModel) cellsView.getSelectionModel()).verifySelectedCells(selectedCells);
+            //Just like the selected cell we update the focused cell.
+            if(finalPair != null && finalPair.getKey() < getGrid().getRowCount() && finalPair.getValue() < getGrid().getColumnCount()){
+                cellsView.getFocusModel().focus(finalPair.getKey(), cellsView.getColumns().get(finalPair.getValue()));
+            }
+        };
+        
+        if (Platform.isFxApplicationThread()) {
+            runnable.run();
+        } else {
+            try {
+                FutureTask future = new FutureTask(runnable, null);
+                Platform.runLater(future);
+                future.get();
+            } catch (InterruptedException | ExecutionException ex) {
+                Logger.getLogger(SpreadsheetView.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        }
+    }
+
+    /**
+     * Return a {@link TablePosition} of cell being currently edited.
+     * 
+     * @return a {@link TablePosition} of cell being currently edited.
+     */
+    public TablePosition<ObservableList<SpreadsheetCell>, ?> getEditingCell() {
+        return cellsView.getEditingCell();
+    }
+    
+    /**
+     * Represents the current cell being edited, or null if there is no cell
+     * being edited.
+     *
+     * @return the current cell being edited, or null if there is no cell being
+     * edited.
+     */
+    public ReadOnlyObjectProperty<TablePosition<ObservableList<SpreadsheetCell>, ?>> editingCellProperty() {
+        return cellsView.editingCellProperty();
+    }
+
+    /**
+     * Return an ObservableList of the {@link SpreadsheetColumn} used. This list
+     * is filled automatically by the SpreadsheetView. Adding and removing
+     * columns should be done in the model {@link Grid}.
+     *
+     * @return An ObservableList of the {@link SpreadsheetColumn}
+     */
+    public final ObservableList<SpreadsheetColumn> getColumns() {
+        return columns;
+    }
+
+    /**
+     * Return the model Grid used by the SpreadsheetView
+     * 
+     * @return the model Grid used by the SpreadsheetView
+     */
+    public final Grid getGrid() {
+        return gridProperty.get();
+    }
+
+    /**
+     * Return a {@link ReadOnlyObjectProperty} containing the current Grid
+     * used in the SpreadsheetView.
+     * @return a {@link ReadOnlyObjectProperty}.
+     */
+    public final ReadOnlyObjectProperty<Grid> gridProperty() {
+        return gridProperty;
+    }
+
+    /**
+     * You can fix or unfix a row by modifying this list. Call
+     * {@link #isRowFixable(int)} before trying to fix a row. See
+     * {@link SpreadsheetView} description for information.
+     *
+     * @return an ObservableList of integer representing the fixedRows.
+     */
+    public ObservableList<Integer> getFixedRows() {
+        return fixedRows;
+    }
+
+    /**
+     * Indicate whether a row can be fixed or not. Call that method before
+     * adding an item with {@link #getFixedRows()} .
+     *
+     * A row cannot be fixed alone if any cell inside the row has a row span
+     * superior to one.
+     *
+     * @param row
+     * @return true if the row can be fixed.
+     */
+    public boolean isRowFixable(int row) {
+        return row >= 0 && row < rowFix.size() && isFixingRowsAllowed() ? rowFix.get(row) : false;
+    }
+    
+    /**
+     * Indicates whether a List of rows can be fixed or not.
+     *
+     * A set of rows cannot be fixed if any cell inside these rows has a row
+     * span superior to the number of fixed rows.
+     *
+     * @param list
+     * @return true if the List of row can be fixed together.
+     */
+    public boolean areRowsFixable(List<? extends Integer> list) {
+        if(list == null || list.isEmpty() || !isFixingRowsAllowed()){
+            return false;
+        }
+        final Grid grid = getGrid();
+        final int rowCount = grid.getRowCount();
+        final ObservableList<ObservableList<SpreadsheetCell>> rows = grid.getRows();
+        for (Integer row : list) {
+            if (row == null || row < 0 || row >= rowCount) {
+                return false;
+            }
+            //If this row is not fixable, we need to identify the maximum span
+            if (!isRowFixable(row)) {
+                int maxSpan = 1;
+                List<SpreadsheetCell> gridRow = rows.get(row);
+                for (SpreadsheetCell cell : gridRow) {
+                    //If the original row is not within this range, there is not need to look deeper.
+                    if (!list.contains(cell.getRow())) {
+                        return false;
+                    }
+                    //We only want to consider the original cell.
+                    if (cell.getRowSpan() > maxSpan && cell.getRow() == row) {
+                        maxSpan = cell.getRowSpan();
+                    }
+                }
+                //Then we need to verify that all rows within that span are fixed.
+                int count = row + maxSpan - 1;
+                for (int index = row + 1; index <= count; ++index) {
+                    if (!list.contains(index)) {
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Return whether change to Fixed rows are allowed.
+     *
+     * @return whether change to Fixed rows are allowed.
+     */
+    public boolean isFixingRowsAllowed() {
+        return fixingRowsAllowedProperty.get();
+    }
+
+    /**
+     * If set to true, user will be allowed to fix and unfix the rows.
+     *
+     * @param b
+     */
+    public void setFixingRowsAllowed(boolean b) {
+        fixingRowsAllowedProperty.set(b);
+    }
+
+    /**
+     * Return the Boolean property associated with the allowance of fixing or
+     * unfixing some rows.
+     *
+     * @return the Boolean property associated with the allowance of fixing or
+     * unfixing some rows.
+     */
+    public ReadOnlyBooleanProperty fixingRowsAllowedProperty() {
+        return fixingRowsAllowedProperty;
+    }
+
+    /**
+     * You can fix or unfix a column by modifying this list. Call
+     * {@link SpreadsheetColumn#isColumnFixable()} on the column before adding
+     * an item.
+     *
+     * @return an ObservableList of the fixed columns.
+     */
+    public ObservableList<SpreadsheetColumn> getFixedColumns() {
+        return fixedColumns;
+    }
+
+    /**
+     * Indicate whether this column can be fixed or not. If you have a
+     * {@link SpreadsheetColumn}, call
+     * {@link SpreadsheetColumn#isColumnFixable()} on it directly. Call that
+     * method before adding an item with {@link #getFixedColumns()} .
+     *
+     * @param columnIndex
+     * @return true if the column if fixable
+     */
+    public boolean isColumnFixable(int columnIndex) {
+        return columnIndex >= 0 && columnIndex < getColumns().size() && isFixingColumnsAllowed()
+                ? getColumns().get(columnIndex).isColumnFixable() : false;
+    }
+
+    /**
+     * Indicates whether a List of {@link SpreadsheetColumn} can be fixed or
+     * not.
+     *
+     * A set of columns cannot be fixed if any cell inside these columns has a
+     * column span superior to the number of fixed columns.
+     *
+     * @param list
+     * @return true if the List of columns can be fixed together.
+     */
+    public boolean areSpreadsheetColumnsFixable(List<? extends SpreadsheetColumn> list) {
+        List<Integer> newList = new ArrayList<>();
+        for (SpreadsheetColumn column : list) {
+            if (column != null) {
+                newList.add(columns.indexOf(column));
+            }
+        }
+        return areColumnsFixable(newList);
+    }
+
+    /**
+     * This method is the same as {@link #areSpreadsheetColumnsFixable(java.util.List)
+     * } but is using a List of {@link SpreadsheetColumn} indexes.
+     *
+     * A set of columns cannot be fixed if any cell inside these columns has a
+     * column span superior to the number of fixed columns.
+     *
+     * @param list
+     * @return true if the List of columns can be fixed together.
+     */
+    public boolean areColumnsFixable(List<? extends Integer> list) {
+        if (list == null || list.isEmpty() || !isFixingRowsAllowed()) {
+            return false;
+        }
+        final Grid grid = getGrid();
+        final int columnCount = grid.getColumnCount();
+        final ObservableList<ObservableList<SpreadsheetCell>> rows = grid.getRows();
+        for (Integer columnIndex : list) {
+            if (columnIndex == null || columnIndex < 0 || columnIndex >= columnCount) {
+                return false;
+            }
+            //If this column is not fixable, we need to identify the maximum span
+            if (!isColumnFixable(columnIndex)) {
+                int maxSpan = 1;
+                SpreadsheetCell cell;
+                for (List<SpreadsheetCell> row : rows) {
+                    cell = row.get(columnIndex);
+                    //If the original column is not within this range, there is not need to look deeper.
+                    if (!list.contains(cell.getColumn())) {
+                        return false;
+                    }
+                    //We only want to consider the original cell.
+                    if (cell.getColumnSpan() > maxSpan && cell.getColumn() == columnIndex) {
+                        maxSpan = cell.getColumnSpan();
+                    }
+                }
+                //Then we need to verify that all columns within that span are fixed.
+                int count = columnIndex + maxSpan - 1;
+                for (int index = columnIndex + 1; index <= count; ++index) {
+                    if (!list.contains(index)) {
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+    
+    /**
+     * Return whether change to Fixed columns are allowed.
+     *
+     * @return whether change to Fixed columns are allowed.
+     */
+    public boolean isFixingColumnsAllowed() {
+        return fixingColumnsAllowedProperty.get();
+    }
+
+    /**
+     * If set to true, user will be allowed to fix and unfix the columns.
+     *
+     * @param b
+     */
+    public void setFixingColumnsAllowed(boolean b) {
+        fixingColumnsAllowedProperty.set(b);
+    }
+
+    /**
+     * Return the Boolean property associated with the allowance of fixing or
+     * unfixing some columns.
+     *
+     * @return the Boolean property associated with the allowance of fixing or
+     * unfixing some columns.
+     */
+    public ReadOnlyBooleanProperty fixingColumnsAllowedProperty() {
+        return fixingColumnsAllowedProperty;
+    }
+
+    /**
+     * Activate and deactivate the Column Header
+     *
+     * @param b
+     */
+    public final void setShowColumnHeader(final boolean b) {
+        showColumnHeader.setValue(b);
+    }
+
+    /**
+     * Return if the Column Header is showing.
+     *
+     * @return a boolean telling whether the column Header is shown
+     */
+    public final boolean isShowColumnHeader() {
+        return showColumnHeader.get();
+    }
+
+    /**
+     * BooleanProperty associated with the column Header.
+     *
+     * @return the BooleanProperty associated with the column Header.
+     */
+    public final BooleanProperty showColumnHeaderProperty() {
+        return showColumnHeader;
+    }
+
+    /**
+     * Activate and deactivate the Row Header.
+     *
+     * @param b
+     */
+    public final void setShowRowHeader(final boolean b) {
+        showRowHeader.setValue(b);
+    }
+
+    /**
+     * Return if the row Header is showing.
+     *
+     * @return a boolean telling if the row Header is being shown
+     */
+    public final boolean isShowRowHeader() {
+        return showRowHeader.get();
+    }
+
+    /**
+     * BooleanProperty associated with the row Header.
+     *
+     * @return the BooleanProperty associated with the row Header.
+     */
+    public final BooleanProperty showRowHeaderProperty() {
+        return showRowHeader;
+    }
+
+    /**
+     * This DoubleProperty represents the with of the rowHeader. This is just
+     * representing the width of the Labels, not the pickers.
+     *
+     * @return A DoubleProperty.
+     */
+    public final DoubleProperty rowHeaderWidthProperty(){
+        return rowHeaderWidth;
+    }
+    
+    /**
+     * Specify a new width for the row header.
+     *
+     * @param value
+     */
+    public final void setRowHeaderWidth(double value){
+        rowHeaderWidth.setValue(value);
+    }
+    
+    /**
+     *
+     * @return the current width of the row header.
+     */
+    public final double getRowHeaderWidth(){
+        return rowHeaderWidth.get();
+    }
+    
+    /**
+     * @return An ObservableMap with the row index as key and the Picker as a
+     * value.
+     */
+    public ObservableMap<Integer, Picker> getRowPickers() {
+        return rowPickers;
+    }
+
+    /**
+     * @return An ObservableMap with the column index as key and the Picker as a
+     * value.
+     */
+    public ObservableMap<Integer, Picker> getColumnPickers() {
+        return columnPickers;
+    }
+
+    /**
+     * This method will compute the best height for each line. That is to say
+     * a height where each content of each cell could be fully visible.\n
+     * Use this method wisely because it can degrade performance on great grid.
+     */
+    public void resizeRowsToFitContent() {
+        if (getCellsViewSkin() != null) {
+            getCellsViewSkin().resizeRowsToFitContent();
+        }
+    }
+    
+    /**
+     * This method will first apply {@link #resizeRowsToFitContent() } and then
+     * take the highest height and apply it to every row.\n
+     * Just as {@link #resizeRowsToFitContent() }, this method can be degrading
+     * your performance on great grid.
+     */
+    public void resizeRowsToMaximum(){
+        if (getCellsViewSkin() != null) {
+            getCellsViewSkin().resizeRowsToMaximum();
+        }
+    }
+    
+    /**
+     * This method will wipe all changes made to the row's height and set all row's
+     * height back to their default height defined in the model Grid.
+     */
+    public void resizeRowsToDefault() {
+        if (getCellsViewSkin() != null) {
+            getCellsViewSkin().resizeRowsToDefault();
+        }
+    }
+    
+    /**
+     * @param row
+     * @return the height of a particular row of the SpreadsheetView.
+     */
+    public double getRowHeight(int row) {
+        //Sometime, the skin is not initialised yet..
+        if (getCellsViewSkin() == null) {
+            return getGrid().getRowHeight(row);
+        } else {
+            return getCellsViewSkin().getRowHeight(row);
+        }
+    }
+    
+    /**
+     * Return the selectionModel used by the SpreadsheetView. 
+     * 
+     * @return {@link SpreadsheetViewSelectionModel}
+     */
+    public SpreadsheetViewSelectionModel getSelectionModel() {
+        return selectionModel;
+    }
+    
+    /**
+     * Scrolls the SpreadsheetView so that the given row is visible.
+     * @param row 
+     */
+    public void scrollToRow(int row){
+        cellsView.scrollTo(row);
+    }
+    
+    /**
+     * Same method as {@link ScrollBar#setValue(double) } on the verticalBar.
+     *
+     * @param value
+     */
+    public void setVBarValue(double value) {
+        if (getCellsViewSkin() == null) {
+            Platform.runLater(() -> {
+                setVBarValue(value);
+            });
+            return;
+        }
+        getCellsViewSkin().getVBar().setValue(value);
+    }
+
+    /**
+     * Same method as {@link ScrollBar#setValue(double) } on the verticalBar.
+     *
+     * @param value
+     */
+    public void setHBarValue(double value) {
+        setHBarValue(value,0);
+    }
+    
+    private void setHBarValue(double value, int attempt) {
+        if(attempt > 10){
+            return;
+        }
+        if (getCellsViewSkin() == null) {
+            final int newAttempt = ++attempt;
+            Platform.runLater(() -> {
+                setHBarValue(value, newAttempt);
+            });
+            return;
+        }
+        getCellsViewSkin().setHbarValue(value);
+    }
+
+    /**
+     * Return the value of the vertical scrollbar. See {@link ScrollBar#getValue()
+     * }
+     *
+     * @return
+     */
+    public double getVBarValue() {
+        if (getCellsViewSkin() != null && getCellsViewSkin().getVBar() != null) {
+            return getCellsViewSkin().getVBar().getValue();
+        }
+        return 0.0;
+    }
+
+    /**
+     * Return the value of the horizontal scrollbar. See {@link ScrollBar#getValue()
+     * }
+     *
+     * @return
+     */
+    public double getHBarValue() {
+        if (getCellsViewSkin() != null && getCellsViewSkin().getHBar() != null) {
+            return getCellsViewSkin().getHBar().getValue();
+        }
+        return 0.0;
+    }
+    
+    /**
+     * Scrolls the SpreadsheetView so that the given {@link SpreadsheetColumn} is visible.
+     * @param column 
+     */
+    public void scrollToColumn(SpreadsheetColumn column){
+        cellsView.scrollToColumn(column.column);
+    }
+    
+    /**
+     *
+     * Scrolls the SpreadsheetView so that the given column index is visible.
+     *
+     * @param columnIndex
+     *
+     */
+    public void scrollToColumnIndex(int columnIndex) {
+        cellsView.scrollToColumnIndex(columnIndex);
+    }
+
+    /**
+     * Return the editor associated with the CellType. (defined in
+     * {@link SpreadsheetCellType#createEditor(SpreadsheetView)}. FIXME Maybe
+     * keep the editor references inside the SpreadsheetCellType
+     * 
+     * @param cellType
+     * @return the editor associated with the CellType.
+     */
+    public final Optional<SpreadsheetCellEditor> getEditor(SpreadsheetCellType<?> cellType) {
+        if(cellType == null){
+            return Optional.empty();
+        }
+        SpreadsheetCellEditor cellEditor = editors.get(cellType);
+        if (cellEditor == null) {
+            cellEditor = cellType.createEditor(this);
+            if(cellEditor == null){
+                return Optional.empty();
+            }
+            editors.put(cellType, cellEditor);
+        }
+        return Optional.of(cellEditor);
+    }
+
+    /**
+     * Sets the value of the property editable.
+     * 
+     * @param b
+     */
+    public final void setEditable(final boolean b) {
+        cellsView.setEditable(b);
+    }
+
+    /**
+     * Gets the value of the property editable.
+     * 
+     * @return a boolean telling if the SpreadsheetView is editable.
+     */
+    public final boolean isEditable() {
+        return cellsView.isEditable();
+    }
+
+    /**
+     * Specifies whether this SpreadsheetView is editable - only if the
+     * SpreadsheetView, and the {@link SpreadsheetCell} within it are both
+     * editable will a {@link SpreadsheetCell} be able to go into its editing
+     * state.
+     * 
+     * @return the BooleanProperty associated with the editableProperty.
+     */
+    public final BooleanProperty editableProperty() {
+        return cellsView.editableProperty();
+    }
+
+    /**
+     * This Node is shown to the user when the SpreadsheetView has no content to show.
+     */
+    public final ObjectProperty<Node> placeholderProperty() {
+        return cellsView.placeholderProperty();
+    }
+
+    /**
+     * Sets the value of the placeholder property
+     *
+     * @param placeholder the node to show when the SpreadsheetView has no content to show.
+     */
+    public final void setPlaceholder(final Node placeholder) {
+        cellsView.setPlaceholder(placeholder);
+    }
+
+    /**
+     * Gets the value of the placeholder property.
+     *
+     * @return the Node used as a placeholder that is shown when the SpreadsheetView has no content to show.
+     */
+    public final Node getPlaceholder() {
+        return cellsView.getPlaceholder();
+    }
+
+    
+    /***************************************************************************
+     * COPY / PASTE METHODS
+     **************************************************************************/
+    
+    /**
+     * Put the current selection into the ClipBoard. This can be overridden by
+     * developers for custom behavior.
+     */
+    public void copyClipboard() {
+        checkFormat();
+
+        final ArrayList<GridChange> list = new ArrayList<>();
+        final ObservableList<TablePosition> posList = getSelectionModel().getSelectedCells();
+
+        for (final TablePosition<?, ?> p : posList) {
+            SpreadsheetCell cell = getGrid().getRows().get(p.getRow()).get(p.getColumn());
+            // Using SpreadsheetCell change to stock the information
+            // FIXME a dedicated class should be used
+            /**
+             * We need to add every cell contained in a span otherwise the
+             * rectangles computed when pasting will be wrong.
+             */
+            for (int row = 0; row < cell.getRowSpan(); ++row) {
+                for (int col = 0; col < cell.getColumnSpan(); ++col) {
+                    try {
+                        new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(cell.getItem());
+                        list.add(new GridChange(cell.getRow() + row, cell.getColumn() + col, null, cell.getItem() == null ? null : cell.getItem()));
+                    } catch (IOException exception) {
+                        list.add(new GridChange(cell.getRow() + row, cell.getColumn() + col, null, cell.getItem() == null ? null : cell.getItem().toString()));
+                    }
+                }
+            }
+        }
+        final ClipboardContent content = new ClipboardContent();
+        content.put(fmt, list);
+        Clipboard.getSystemClipboard().setContent(content);
+    }
+
+    /**
+     * Paste one value from the clipboard over the whole selection.
+     * @param change 
+     */
+    private void pasteOneValue(GridChange change) {
+        for (TablePosition position : getSelectionModel().getSelectedCells()) {
+            tryPasteCell(position.getRow(), position.getColumn(), change.getNewValue());
+        }
+    }
+
+    /**
+     * Try to paste the given value into the given position.
+     * @param row
+     * @param column
+     * @param value 
+     */
+    private void tryPasteCell(int row, int column, Object value) {
+        final SpanType type = getSpanType(row, column);
+        if (type == SpanType.NORMAL_CELL || type == SpanType.ROW_VISIBLE) {
+            SpreadsheetCell cell = getGrid().getRows().get(row).get(column);
+            boolean succeed = cell.getCellType().match(value);
+            if (succeed) {
+                getGrid().setCellValue(cell.getRow(), cell.getColumn(),
+                        cell.getCellType().convertValue(value));
+            }
+        }
+    }
+
+    /**
+     * Try to paste the values given into the selection. If both selection are
+     * rectangles and the number of rows of the source is equal of the numbers
+     * of rows of the target AND number of columns of the target is a multiple
+     * of the number of columns of the source, then we can paste.
+     *
+     * Same goes if we invert the rows and columns.
+     * @param list
+     */
+    private void pasteMixedValues(ArrayList<GridChange> list) {
+        SelectionRange sourceSelectionRange = new SelectionRange();
+        sourceSelectionRange.fillGridRange(list);
+
+        //It means we have a rectangle.
+        if (sourceSelectionRange.getRange() != null) {
+            SelectionRange targetSelectionRange = new SelectionRange();
+            targetSelectionRange.fill(cellsView.getSelectionModel().getSelectedCells());
+            if (targetSelectionRange.getRange() != null) {
+                //If both selection are rectangle
+                GridRange sourceRange = sourceSelectionRange.getRange();
+                GridRange targetRange = targetSelectionRange.getRange();
+                int sourceRowGap = sourceRange.getBottom() - sourceRange.getTop() + 1;
+                int targetRowGap = targetRange.getBottom() - targetRange.getTop() + 1;
+
+                int sourceColumnGap = sourceRange.getRight() - sourceRange.getLeft() + 1;
+                int targetColumnGap = targetRange.getRight() - targetRange.getLeft() + 1;
+
+                final int offsetRow = targetRange.getTop() - sourceRange.getTop();
+                final int offsetCol = targetRange.getLeft() - sourceRange.getLeft();
+
+                //If the numbers of rows are the same and the targetColumnGap is a multiple of sourceColumnGap
+                if ((sourceRowGap == targetRowGap || targetRowGap == 1) && (targetColumnGap % sourceColumnGap) == 0) {
+                    for (final GridChange change : list) {
+                        int row = change.getRow() + offsetRow;
+                        int column = change.getColumn() + offsetCol;
+                        do {
+                            if (row < getGrid().getRowCount() && column < getGrid().getColumnCount()
+                                    && row >= 0 && column >= 0) {
+                                tryPasteCell(row, column, change.getNewValue());
+                            }
+                        } while ((column = column + sourceColumnGap) <= targetRange.getRight());
+                    }
+                    //If the numbers of columns are the same and the targetRowGap is a multiple of sourceRowGap
+                } else if ((sourceColumnGap == targetColumnGap || targetColumnGap == 1) && (targetRowGap % sourceRowGap) == 0) {
+                    for (final GridChange change : list) {
+
+                        int row = change.getRow() + offsetRow;
+                        int column = change.getColumn() + offsetCol;
+                        do {
+                            if (row < getGrid().getRowCount() && column < getGrid().getColumnCount()
+                                    && row >= 0 && column >= 0) {
+                                tryPasteCell(row, column, change.getNewValue());
+                            }
+                        } while ((row = row + sourceRowGap) <= targetRange.getBottom());
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * If we have several source values to paste into one cell, we do it.
+     *
+     * @param list
+     */
+    private void pasteSeveralValues(ArrayList<GridChange> list) {
+        // TODO algorithm very bad
+        int minRow = getGrid().getRowCount();
+        int minCol = getGrid().getColumnCount();
+        int maxRow = 0;
+        int maxCol = 0;
+        for (final GridChange p : list) {
+            final int tempcol = p.getColumn();
+            final int temprow = p.getRow();
+            if (tempcol < minCol) {
+                minCol = tempcol;
+            }
+            if (tempcol > maxCol) {
+                maxCol = tempcol;
+            }
+            if (temprow < minRow) {
+                minRow = temprow;
+            }
+            if (temprow > maxRow) {
+                maxRow = temprow;
+            }
+        }
+
+        final TablePosition<?, ?> p = cellsView.getFocusModel().getFocusedCell();
+
+        final int offsetRow = p.getRow() - minRow;
+        final int offsetCol = p.getColumn() - minCol;
+        final int rowCount = getGrid().getRowCount();
+        final int columnCount = getGrid().getColumnCount();
+        int row;
+        int column;
+
+        for (final GridChange change : list) {
+            row = change.getRow() + offsetRow;
+            column = change.getColumn() + offsetCol;
+            if (row < rowCount && column < columnCount
+                    && row >= 0 && column >= 0) {
+                tryPasteCell(row, column, change.getNewValue());
+            }
+        }
+    }
+    
+    /**
+     * Try to paste the clipBoard to the specified position. Try to paste the
+     * current selection into the Grid. If the two contents are not matchable,
+     * then it's not pasted. This can be overridden by developers for custom
+     * behavior.
+     */
+    public void pasteClipboard() {
+        // FIXME Maybe move editableProperty to the model..
+        List<TablePosition> selectedCells = cellsView.getSelectionModel().getSelectedCells();
+        if (!isEditable() || selectedCells.isEmpty()) {
+            return;
+        }
+
+        checkFormat();
+        final Clipboard clipboard = Clipboard.getSystemClipboard();
+        
+        if (clipboard.getContent(fmt) != null) {
+
+            @SuppressWarnings("unchecked")
+            final ArrayList<GridChange> list = (ArrayList<GridChange>) clipboard.getContent(fmt);
+            if (list.size() == 1) {
+                pasteOneValue(list.get(0));
+            } else if (selectedCells.size() > 1) {
+                pasteMixedValues(list);
+            } else {
+                pasteSeveralValues(list);
+            }
+            // To be improved
+        } else if (clipboard.hasString()) {
+        	ArrayList<GridChange> list = new ArrayList<>();
+        	String str = clipboard.getString();
+
+        	String[] lines = str.split("\r");        	
+        	for(int i = 0; i < lines.length; ++i) {
+        		String line = lines[i];
+        		String[] cells = line.split("\t");
+        		
+        		for(int j = 0; j < cells.length; ++ j) {
+        			String cell = cells[j];
+        			list.add(new GridChange(i, j, cell, cell));
+        		}     
+        		
+        	}
+        	
+            if (list.size() == 1) {
+                pasteOneValue(list.get(0));
+            } else if (selectedCells.size() > 1) {
+                pasteMixedValues(list);
+            } else {
+                pasteSeveralValues(list);
+            }
+        	
+        	/*
+             final TablePosition<?,?> p =
+             cellsView.getFocusModel().getFocusedCell();
+            //
+             SpreadsheetCell stringCell =
+             SpreadsheetCellType.STRING.createCell(0, 0, 1, 1,
+             clipboard.getString());
+             getGrid().getRows().get(p.getRow()).get(p.getColumn()).match(stringCell);*/
+        }
+    }
+
+    /**
+     * Create a menu on rightClick with two options: Copy/Paste This can be
+     * overridden by developers for custom behavior.
+     * 
+     * @return the ContextMenu to use.
+     */
+    public ContextMenu getSpreadsheetViewContextMenu() {
+        final ContextMenu contextMenu = new ContextMenu();
+
+        final MenuItem copyItem = new MenuItem(localize(asKey("spreadsheet.view.menu.copy"))); //$NON-NLS-1$
+        copyItem.setGraphic(new ImageView(new Image(SpreadsheetView.class
+                .getResourceAsStream("copySpreadsheetView.png")))); //$NON-NLS-1$
+        copyItem.setAccelerator(new KeyCodeCombination(KeyCode.C, KeyCombination.SHORTCUT_DOWN));
+        copyItem.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent e) {
+                copyClipboard();
+            }
+        });
+
+        final MenuItem pasteItem = new MenuItem(localize(asKey("spreadsheet.view.menu.paste"))); //$NON-NLS-1$
+        pasteItem.setGraphic(new ImageView(new Image(SpreadsheetView.class
+                .getResourceAsStream("pasteSpreadsheetView.png")))); //$NON-NLS-1$
+        pasteItem.setAccelerator(new KeyCodeCombination(KeyCode.V, KeyCombination.SHORTCUT_DOWN));
+        pasteItem.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent e) {
+                pasteClipboard();
+            }
+        });
+        
+        final Menu cornerMenu = new Menu(localize(asKey("spreadsheet.view.menu.comment"))); //$NON-NLS-1$
+        cornerMenu.setGraphic(new ImageView(new Image(SpreadsheetView.class
+                .getResourceAsStream("comment.png")))); //$NON-NLS-1$
+
+        final MenuItem topLeftItem = new MenuItem(localize(asKey("spreadsheet.view.menu.comment.top-left"))); //$NON-NLS-1$
+        topLeftItem.setOnAction(new EventHandler<ActionEvent>() {
+
+            @Override
+            public void handle(ActionEvent t) {
+                TablePosition<ObservableList<SpreadsheetCell>, ?> pos = cellsView.getFocusModel().getFocusedCell();
+                SpreadsheetCell cell = getGrid().getRows().get(pos.getRow()).get(pos.getColumn());
+                cell.activateCorner(SpreadsheetCell.CornerPosition.TOP_LEFT);
+                }
+        });
+        final MenuItem topRightItem = new MenuItem(localize(asKey("spreadsheet.view.menu.comment.top-right"))); //$NON-NLS-1$
+        topRightItem.setOnAction(new EventHandler<ActionEvent>() {
+
+            @Override
+            public void handle(ActionEvent t) {
+                TablePosition<ObservableList<SpreadsheetCell>, ?> pos = cellsView.getFocusModel().getFocusedCell();
+                SpreadsheetCell cell = getGrid().getRows().get(pos.getRow()).get(pos.getColumn());
+                cell.activateCorner(SpreadsheetCell.CornerPosition.TOP_RIGHT);
+            }
+        });
+        final MenuItem bottomRightItem = new MenuItem(localize(asKey("spreadsheet.view.menu.comment.bottom-right"))); //$NON-NLS-1$
+        bottomRightItem.setOnAction(new EventHandler<ActionEvent>() {
+
+            @Override
+            public void handle(ActionEvent t) {
+                TablePosition<ObservableList<SpreadsheetCell>, ?> pos = cellsView.getFocusModel().getFocusedCell();
+                SpreadsheetCell cell = getGrid().getRows().get(pos.getRow()).get(pos.getColumn());
+                cell.activateCorner(SpreadsheetCell.CornerPosition.BOTTOM_RIGHT);
+            }
+        });
+        final MenuItem bottomLeftItem = new MenuItem(localize(asKey("spreadsheet.view.menu.comment.bottom-left"))); //$NON-NLS-1$
+        bottomLeftItem.setOnAction(new EventHandler<ActionEvent>() {
+
+            @Override
+            public void handle(ActionEvent t) {
+                TablePosition<ObservableList<SpreadsheetCell>, ?> pos = cellsView.getFocusModel().getFocusedCell();
+                SpreadsheetCell cell = getGrid().getRows().get(pos.getRow()).get(pos.getColumn());
+                cell.activateCorner(SpreadsheetCell.CornerPosition.BOTTOM_LEFT);
+            }
+        });
+
+        cornerMenu.getItems().addAll(topLeftItem, topRightItem, bottomRightItem, bottomLeftItem);
+        
+        contextMenu.getItems().addAll(copyItem, pasteItem, cornerMenu);
+        return contextMenu;
+    }
+
+    /**
+     * This method is called when pressing the "delete" key on the
+     * SpreadsheetView. This will erase the values of selected cells. This can
+     * be overridden by developers for custom behavior.
+     */
+    public void deleteSelectedCells() {
+        for (TablePosition<ObservableList<SpreadsheetCell>, ?> position : getSelectionModel().getSelectedCells()) {
+            getGrid().setCellValue(position.getRow(), position.getColumn(), null);
+        }
+    }
+    
+     /**
+     * Return the {@link SpanType} of a cell, this is a shorcut for 
+     * {@link Grid#getSpanType(org.controlsfx.control.spreadsheet.SpreadsheetView, int, int) }.
+     * 
+     * @param row
+     * @param column
+     * @return The {@link SpanType} of a cell
+     */
+    public SpanType getSpanType(final int row, final int column) {
+        if (getGrid() == null) {
+            return SpanType.NORMAL_CELL;
+        }
+        return getGrid().getSpanType(this, row, column);
+    }
+
+    /***************************************************************************
+     * * Private/Protected Implementation * *
+     **************************************************************************/
+
+    /**
+     * This is called when setting a Grid. The main idea is to re-use
+     * TableColumn if possible. Because we can have a great amount of time spent
+     * in com.sun.javafx.css.StyleManager.forget when removing lots of columns
+     * and adding new ones. So if we already have some, we can just re-use them
+     * so we avoid doign all the fuss with the TableColumns.
+     *
+     * @param grid
+     * @param columnIndex
+     * @return
+     */
+    private TableColumn<ObservableList<SpreadsheetCell>, SpreadsheetCell> getTableColumn(Grid grid, int columnIndex) {
+
+        TableColumn<ObservableList<SpreadsheetCell>, SpreadsheetCell> column;
+
+        String columnHeader = grid.getColumnHeaders().size() > columnIndex ? grid
+                .getColumnHeaders().get(columnIndex) : Utils.getExcelLetterFromNumber(columnIndex);
+
+        if (columnIndex < cellsView.getColumns().size()) {
+            column = (TableColumn<ObservableList<SpreadsheetCell>, SpreadsheetCell>) cellsView.getColumns().get(columnIndex);
+            column.setText(columnHeader);
+        } else {
+            column = new TableColumn<>(columnHeader);
+
+            column.setEditable(true);
+            // We don't want to sort the column
+            column.setSortable(false);
+
+            column.impl_setReorderable(false);
+
+            // We assign a DataCell for each Cell needed (MODEL).
+            column.setCellValueFactory((TableColumn.CellDataFeatures<ObservableList<SpreadsheetCell>, SpreadsheetCell> p) -> {
+                if (columnIndex >= p.getValue().size()) {
+                    return null;
+                }
+                return new ReadOnlyObjectWrapper<>(p.getValue().get(columnIndex));
+            });
+            // We create a SpreadsheetCell for each DataCell in order to
+            // specify how to represent the DataCell(VIEW)
+            column.setCellFactory((TableColumn<ObservableList<SpreadsheetCell>, SpreadsheetCell> p) -> new CellView(handle));
+        }
+        return column;
+    }
+    
+    /**
+     * This static method creates a sample Grid with 100 rows and 15 columns.
+     * All cells are typed as String.
+     *
+     * @return the sample Grid
+     * @see SpreadsheetCellType#STRING
+     */
+    private static Grid getSampleGrid() {
+        GridBase gridBase = new GridBase(100, 15);
+        List<ObservableList<SpreadsheetCell>> rows = FXCollections.observableArrayList();
+
+        for (int row = 0; row < gridBase.getRowCount(); ++row) {
+            ObservableList<SpreadsheetCell> currentRow = FXCollections.observableArrayList();
+            for (int column = 0; column < gridBase.getColumnCount(); ++column) {
+                currentRow.add(SpreadsheetCellType.STRING.createCell(row, column, 1, 1, "toto"));
+            }
+            rows.add(currentRow);
+        }
+        gridBase.setRows(rows);
+        return gridBase;
+    }
+    
+    private void initRowFix(Grid grid) {
+        ObservableList<ObservableList<SpreadsheetCell>> rows = grid.getRows();
+        rowFix = new BitSet(rows.size());
+        rows:
+        for (int r = 0; r < rows.size(); ++r) {
+            ObservableList<SpreadsheetCell> row = rows.get(r);
+            for (SpreadsheetCell cell : row) {
+                if (cell.getRowSpan() > 1) {
+                    continue rows;
+                }
+            }
+            rowFix.set(r);
+        }
+    }
+    
+    /**
+     * Verify that the grid is well-formed. Can be quite time-consuming I guess
+     * so I would like it not to be compulsory..
+     * 
+     * @param grid
+     */
+    private void verifyGrid(Grid grid) {
+        verifyColumnSpan(grid);
+    }
+
+    private void verifyColumnSpan(Grid grid) {
+        for (int i = 0; i < grid.getRows().size(); ++i) {
+            ObservableList<SpreadsheetCell> row = grid.getRows().get(i);
+            int count = 0;
+            for (int j = 0; j < row.size(); ++j) {
+                if (row.get(j).getColumnSpan() == 1) {
+                    ++count;
+                } else if (row.get(j).getColumnSpan() > 1) {
+                    ++count;
+                    SpreadsheetCell currentCell = row.get(j);
+                    for (int k = j + 1; k < currentCell.getColumn() + currentCell.getColumnSpan(); ++k) {
+                        if (!row.get(k).equals(currentCell)) {
+                            throw new IllegalStateException("\n At row " + i + " and column " + j //$NON-NLS-1$ //$NON-NLS-2$
+                                    + ": this cell is in the range of a columnSpan but is different. \n" //$NON-NLS-1$
+                                    + "Every cell in a range of a ColumnSpan must be of the same instance."); //$NON-NLS-1$
+                        }
+                        ++count;
+                        ++j;
+                    }
+                } else {
+                    throw new IllegalStateException("\n At row " + i + " and column " + j //$NON-NLS-1$ //$NON-NLS-2$
+                            + ": this cell has a negative columnSpan"); //$NON-NLS-1$
+                }
+            }
+            if (count != grid.getColumnCount()) {
+                throw new IllegalStateException("The row" + i //$NON-NLS-1$
+                        + " has a number of cells different of the columnCount declared in the grid."); //$NON-NLS-1$
+            }
+        }
+    }
+
+    private void checkFormat() {
+        if ((fmt = DataFormat.lookupMimeType("SpreadsheetView")) == null) { //$NON-NLS-1$
+            fmt = new DataFormat("SpreadsheetView"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * ********************************************************************* *
+     * private listeners
+     * ********************************************************************
+     */
+
+    private final ListChangeListener<Integer> fixedRowsListener = new ListChangeListener<Integer>() {
+        @Override
+        public void onChanged(ListChangeListener.Change<? extends Integer> c) {
+            while (c.next()) {
+                if (c.wasAdded()) {
+                    List<? extends Integer> newRows = c.getAddedSubList();
+                    if(!areRowsFixable(newRows)){
+                        throw new IllegalArgumentException(computeReason(newRows));
+                    }
+                    FXCollections.sort(fixedRows);
+                }
+                
+                if(c.wasRemoved()){
+                    //Handle this case.
+                }
+            }
+        }
+    };
+
+        private String computeReason(List<? extends Integer> list) {
+        String reason = "\n A row cannot be fixed. \n"; //$NON-NLS-1$
+
+        for (Integer row : list) {
+            //If this row is not fixable, we need to identify the maximum span
+            if (!isRowFixable(row)) {
+
+                int maxSpan = 1;
+                List<SpreadsheetCell> gridRow = getGrid().getRows().get(row);
+                for (SpreadsheetCell cell : gridRow) {
+                    if(!list.contains(cell.getRow())){
+                        reason += "The row " + row + " is inside a row span and the starting row " + cell.getRow() + " is not fixed.\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    }
+                    //We only want to consider the original cell.
+                    if (cell.getRowSpan() > maxSpan && cell.getRow() == row) {
+                        maxSpan = cell.getRowSpan();
+                    }
+                }
+                //Then we need to verify that all rows within that span are fixed.
+                int count = row + maxSpan - 1;
+                for (int index = row + 1; index < count; ++index) {
+                    if (!list.contains(index)) {
+                        reason += "One cell on the row " + row + " has a row span of " + maxSpan + ". " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                                + "But the row " + index + " contained within that span is not fixed.\n"; //$NON-NLS-1$ //$NON-NLS-2$
+                    }
+                }
+            }
+        }
+        return reason;
+    }
+
+    private final ListChangeListener<SpreadsheetColumn> fixedColumnsListener = new ListChangeListener<SpreadsheetColumn>() {
+        @Override
+        public void onChanged(ListChangeListener.Change<? extends SpreadsheetColumn> c) {
+            while (c.next()) {
+                if (c.wasAdded()) {
+                    List<? extends SpreadsheetColumn> newColumns = c.getAddedSubList();
+                    if (!areSpreadsheetColumnsFixable(newColumns)) {
+                        List<Integer> newList = new ArrayList<>();
+                        for (SpreadsheetColumn column : newColumns) {
+                            if (column != null) {
+                                newList.add(columns.indexOf(column));
+                            }
+                        }
+                        throw new IllegalArgumentException(computeReason(newList));
+                    }
+                }
+            }
+        }
+
+        private String computeReason(List<Integer> list) {
+
+            String reason = "\n This column cannot be fixed."; //$NON-NLS-1$
+            final ObservableList<ObservableList<SpreadsheetCell>> rows = getGrid().getRows();
+            for (Integer columnIndex : list) {
+                //If this row is not fixable, we need to identify the maximum span
+                if (!isColumnFixable(columnIndex)) {
+                    int maxSpan = 1;
+                    SpreadsheetCell cell;
+                    for (List<SpreadsheetCell> row : rows) {
+                        cell = row.get(columnIndex);
+                        //If the original column is not within this range, there is not need to look deeper.
+                        if (!list.contains(cell.getColumn())) {
+                            reason += "The column " + columnIndex + " is inside a column span and the starting column " + cell.getColumn() + " is not fixed.\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                        }
+                        //We only want to consider the original cell.
+                        if (cell.getColumnSpan() > maxSpan && cell.getColumn() == columnIndex) {
+                            maxSpan = cell.getColumnSpan();
+                        }
+                    }
+                    //Then we need to verify that all columns within that span are fixed.
+                    int count = columnIndex + maxSpan - 1;
+                    for (int index = columnIndex + 1; index < count; ++index) {
+                        if (!list.contains(index)) {
+                            reason += "One cell on the column " + columnIndex + " has a column span of " + maxSpan + ". " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                                    + "But the column " + index + " contained within that span is not fixed.\n"; //$NON-NLS-1$ //$NON-NLS-2$
+                        }
+                    }
+                }
+            }
+            return reason;
+        }
+    };
+
+    private final ChangeListener<ContextMenu> contextMenuChangeListener = new ChangeListener<ContextMenu>() {
+        
+        @Override
+        public void changed(ObservableValue<? extends ContextMenu> arg0, ContextMenu oldContextMenu, final ContextMenu newContextMenu) {
+            if(oldContextMenu !=null){
+                oldContextMenu.setOnShowing(null);
+            }
+            if(newContextMenu != null){
+                newContextMenu.setOnShowing(new WeakEventHandler<>(hideContextMenuEventHandler));
+            }
+        }
+    };
+    
+    private final EventHandler<WindowEvent> hideContextMenuEventHandler = new EventHandler<WindowEvent>() {
+        @Override
+        public void handle(WindowEvent arg0) {
+            // We don't want to open a contextMenu when editing
+            // because editors
+            // have their own contextMenu
+            if (getEditingCell() != null) {
+                // We're being reactive but we want to be pro-active
+                // so we may need a work-around.
+                Platform.runLater(()->{
+                    getContextMenu().hide();
+                });
+            }
+        }
+    };
+    
+    private final EventHandler<KeyEvent> keyPressedHandler = (KeyEvent keyEvent) -> {
+        TablePosition<ObservableList<SpreadsheetCell>, ?> position = getSelectionModel().getFocusedCell();
+        // Go to the next row only if we're not editing
+        if (getEditingCell() == null && KeyCode.ENTER.equals(keyEvent.getCode())) {
+            if (position != null) {
+                if(keyEvent.isShiftDown()){
+                    getSelectionModel().clearAndSelectPreviousCell();
+                }else{
+                    getSelectionModel().clearAndSelectNextCell();
+                }
+                //We consume the event because we don't want to go in edition
+                keyEvent.consume();
+            }
+            getCellsViewSkin().scrollHorizontally();
+            // Go to next cell
+        } else if (getEditingCell() == null && KeyCode.TAB.equals(keyEvent.getCode())) {
+            if (position != null) {
+                if (keyEvent.isShiftDown()) {
+                    getSelectionModel().clearAndSelectLeftCell();
+                } else {
+                    getSelectionModel().clearAndSelectRightCell();
+                }
+            }
+            //We consume the event because we don't want to loose focus
+            keyEvent.consume();
+            getCellsViewSkin().scrollHorizontally();
+            // We want to erase values when delete key is pressed.
+        } else if (KeyCode.DELETE.equals(keyEvent.getCode())) {
+            deleteSelectedCells();
+            /**
+             * We want NOT to go in edition if we're pressing SHIFT and if we're
+             * using the navigation keys. But we still want the user to go in
+             * edition with SHIFT and some letters for example if he wants a
+             * capital letter.
+             * FIXME Add a test to prevent the Shift fail case.
+             */
+        }else if (keyEvent.getCode() != KeyCode.SHIFT && !keyEvent.isShortcutDown() 
+                && !keyEvent.getCode().isNavigationKey() 
+                && keyEvent.getCode() != KeyCode.ESCAPE) {
+            getCellsView().edit(position.getRow(), position.getTableColumn());
+        }
+    };
+    
+    /**
+     * This event is thrown on the SpreadsheetView when the user resize a row
+     * with its mouse.
+     */
+    public static class RowHeightEvent extends Event {
+
+        /**
+         * This is the event used by {@link RowHeightEvent}.
+         */
+        public static final EventType<RowHeightEvent> ROW_HEIGHT_CHANGE = new EventType<>(Event.ANY, "RowHeightChange"); //$NON-NLS-1$
+
+        private final int row;
+        private final double height;
+
+        public RowHeightEvent(int row, double height) {
+            super(ROW_HEIGHT_CHANGE);
+            this.row = row;
+            this.height = height;
+        }
+
+        /**
+         * Return the row index that has been resized.
+         * @return the row index that has been resized.
+         */
+        public int getRow() {
+            return row;
+        }
+
+        /**
+         * Return the new height for this row.
+         * @return the new height for this row.
+         */
+        public double getHeight() {
+            return height;
+        }
+    }
+    
+    /**
+     * This event is thrown on the SpreadsheetView when the user resize a column
+     * with its mouse.
+     */
+    public static class ColumnWidthEvent extends Event {
+
+        /**
+         * This is the event used by {@link ColumnWidthEvent}.
+         */
+        public static final EventType<ColumnWidthEvent> COLUMN_WIDTH_CHANGE = new EventType<>(Event.ANY, "ColumnWidthChange"); //$NON-NLS-1$
+
+        private final int column;
+        private final double width;
+
+        public ColumnWidthEvent(int column, double width) {
+            super(COLUMN_WIDTH_CHANGE);
+            this.column = column;
+            this.width = width;
+        }
+
+        /**
+         * Return the column index that has been resized.
+         * @return the column index that has been resized.
+         */
+        public int getColumn() {
+            return column;
+        }
+
+        /**
+         * Return the new width for this column.
+         * @return the new width for this column.
+         */
+        public double getWidth() {
+            return width;
+        }
+    }
+
+	public void addedSkin(GridViewSkin viewSkin) {
+		// TODO Auto-generated method stub
+		
+	}
+}
diff --git a/src/org/controlsfx/control/spreadsheet/SpreadsheetViewSelectionModel.java b/src/org/controlsfx/control/spreadsheet/SpreadsheetViewSelectionModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..95611805ddabca158e2451e58d2750c0d1c22a92
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/SpreadsheetViewSelectionModel.java
@@ -0,0 +1,237 @@
+/**
+ * Copyright (c) 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import impl.org.controlsfx.spreadsheet.FocusModelListener;
+import impl.org.controlsfx.spreadsheet.TableViewSpanSelectionModel;
+import java.util.Arrays;
+import java.util.List;
+import javafx.collections.ObservableList;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableView;
+import javafx.util.Pair;
+
+/**
+ *
+ * This class provides basic support for common interaction on the
+ * {@link SpreadsheetView}.
+ *
+ * Due to the complexity induced by cell's span, it is not possible to give a
+ * full access to selectionModel like in the {@link TableView}.
+ */
+public class SpreadsheetViewSelectionModel {
+
+    private final TableViewSpanSelectionModel selectionModel;
+    private final SpreadsheetView spv;
+
+    SpreadsheetViewSelectionModel(SpreadsheetView spv, TableViewSpanSelectionModel selectionModel) {
+        this.spv = spv;
+        this.selectionModel = selectionModel;
+    }
+    
+    /**
+     * Clears all selection, and then selects the cell at the given row/column intersection.
+     * @param row
+     * @param column 
+     */
+    public final void clearAndSelect(int row, SpreadsheetColumn column) {
+        selectionModel.clearAndSelect(row, column.column);
+    }
+    
+    /**
+     * Selects the cell at the given row/column intersection.
+     * @param row
+     * @param column 
+     */
+    public final void select(int row, SpreadsheetColumn column) {
+        selectionModel.select(row,column.column);
+    }
+    
+    /**
+     * Clears the selection model of all selected indices.
+     */
+    public final void clearSelection() {
+        selectionModel.clearSelection();
+    }
+    
+    /**
+     * A read-only ObservableList representing the currently selected cells in this SpreadsheetView. 
+     * @return A read-only ObservableList.
+     */
+    public final ObservableList<TablePosition> getSelectedCells() {
+        return selectionModel.getSelectedCells();
+    }
+    
+    /**
+     * Select all the possible cells.
+     */
+    public final void selectAll() {
+        selectionModel.selectAll();
+    }
+    
+    /**
+     * Return the position of the cell that has current focus. 
+     * @return the position of the cell that has current focus. 
+     */
+    public final TablePosition getFocusedCell(){
+        return selectionModel.getTableView().getFocusModel().getFocusedCell();
+    }
+    
+    /**
+     * Causes the cell at the given index to receive the focus.
+     * @param row The row index of the item to give focus to.
+     * @param column The column of the item to give focus to. Can be null.
+     */
+    public final void focus(int row, SpreadsheetColumn column){
+        selectionModel.getTableView().getFocusModel().focus(row, column.column);
+    }
+    
+    /**
+     * Specifies the selection mode to use in this selection model. The
+     * selection mode specifies how many items in the underlying data model can
+     * be selected at any one time. By default, the selection mode is
+     * {@link SelectionMode#MULTIPLE}.
+     *
+     * @param value
+     */
+    public final void setSelectionMode(SelectionMode value) {
+        selectionModel.setSelectionMode(value);
+    }
+    
+    /**
+     * Return the selectionMode currently used.
+     *
+     * @return the selectionMode currently used.
+     */
+    public SelectionMode getSelectionMode() {
+        return selectionModel.getSelectionMode();
+    }
+    
+    
+    /**
+     * Use this method to select discontinuous cells.
+     *
+     * The {@link Pair} must contain the row index as key and the column index
+     * as value. This is useful when you want to select a great amount of cell
+     * because it will be more efficient than calling
+     * {@link #select(int, org.controlsfx.control.spreadsheet.SpreadsheetColumn) }.
+     *
+     * @param selectedCells
+     */
+    public void selectCells(List<Pair<Integer, Integer>> selectedCells) {
+        selectionModel.verifySelectedCells(selectedCells);
+    }
+    
+    /**
+     * Use this method to select discontinuous cells.
+     *
+     * The {@link Pair} must contain the row index as key and the column index
+     * as value. This is useful when you want to select a great amount of cell
+     * because it will be more efficient than calling
+     * {@link #select(int, org.controlsfx.control.spreadsheet.SpreadsheetColumn) }.
+     * @param selectedCells
+     */
+    public void selectCells(Pair<Integer, Integer>... selectedCells) {
+        selectionModel.verifySelectedCells(Arrays.asList(selectedCells));
+    }
+    
+    /**
+     * Selects the cells in the range (minRow, minColumn) to (maxRow, maxColumn), inclusive.
+     * @param minRow
+     * @param minColumn
+     * @param maxRow
+     * @param maxColumn 
+     */
+    public void selectRange(int minRow, SpreadsheetColumn minColumn, int maxRow, SpreadsheetColumn maxColumn) {
+        selectionModel.selectRange(minRow, minColumn.column, maxRow, maxColumn.column);
+    }
+    
+    /**
+     * Clear the current selection and select the cell on the left of the
+     * current focused cell. If the cell is the first one on a row, the last
+     * cell of the preceding row is selected.
+     */
+    public void clearAndSelectLeftCell() {
+        TablePosition<ObservableList<SpreadsheetCell>, ?> position = getFocusedCell();
+        int row = position.getRow();
+        int column = position.getColumn();
+        column -= 1;
+        if (column < 0) {
+            if (row == 0) {
+                column++;
+            } else {
+                column = spv.getGrid().getColumnCount() - 1;
+                row--;
+            }
+        }
+        clearAndSelect(row, spv.getColumns().get(column));
+    }
+
+    /**
+     * Clear the current selection and select the cell on the right of the
+     * current focused cell. If the cell is the last one on a row, the first
+     * cell of the next row is selected.
+     */
+    public void clearAndSelectRightCell() {
+        TablePosition<ObservableList<SpreadsheetCell>, ?> position = getFocusedCell();
+        int row = position.getRow();
+        int column = position.getColumn();
+        column += 1;
+        if (column >= spv.getColumns().size()) {
+            if (row == spv.getGrid().getRowCount() - 1) {
+                column--;
+            } else {
+                column = 0;
+                row++;
+            }
+        }
+        clearAndSelect(row, spv.getColumns().get(column));
+    }
+
+    /**
+     * Clear the current selection and select the cell on the previous row.
+     */
+    public void clearAndSelectPreviousCell() {
+        TablePosition<ObservableList<SpreadsheetCell>, ?> position = getFocusedCell();
+        int nextRow = FocusModelListener.getPreviousRowNumber(position, selectionModel.getTableView());
+        if (nextRow >= 0) {
+            clearAndSelect(nextRow, spv.getColumns().get(position.getColumn()));
+        }
+    }
+
+    /**
+     * Clear the current selection and select the cell on the next row.
+     */
+    public void clearAndSelectNextCell() {
+        TablePosition<ObservableList<SpreadsheetCell>, ?> position = getFocusedCell();
+        int nextRow = FocusModelListener.getNextRowNumber(position, selectionModel.getTableView());
+        if (nextRow < spv.getGrid().getRowCount()) {
+            clearAndSelect(nextRow, spv.getColumns().get(position.getColumn()));
+        }
+    }
+}
diff --git a/src/org/controlsfx/control/spreadsheet/StringConverterWithFormat.java b/src/org/controlsfx/control/spreadsheet/StringConverterWithFormat.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0b4d41ea9866627c271d3076232c2b9dcde08b0
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/StringConverterWithFormat.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.spreadsheet;
+
+import javafx.util.StringConverter;
+
+/**
+ * This class is used by some of the {@link SpreadsheetCellType} in order to use
+ * a specific format.<br>
+ * 
+ * Since the format is specified in the {@link SpreadsheetCell}, we need a
+ * converter which provide a runtime method {@link #toStringFormat(Object, String)}.<br>
+ * 
+ * This class provide two constructors:
+ * <ul>
+ * <li>A default one where you implement the three abstract methods.</li>
+ * <li>Another one which takes another StringConverter. This is useful when you just want to implement 
+ * the {@link #toStringFormat(Object, String)} and let the other converter handle the other methods.</li>
+ * </ul>
+ * 
+ * @see SpreadsheetCellType
+ * 
+ * @param <T>
+ */
+public abstract class StringConverterWithFormat<T> extends StringConverter<T> {
+
+    protected StringConverter<T> myConverter;
+
+    /**
+     * Default constructor.
+     */
+    public StringConverterWithFormat() {
+        super();
+    }
+
+    /**
+     * This constructor allow to use another StringConverter. 
+     * @param specificStringConverter
+     */
+    public StringConverterWithFormat(StringConverter<T> specificStringConverter) {
+        myConverter = specificStringConverter;
+    }
+
+    /**
+     * Converts the object provided into its string form with the specified format.
+     * @param value
+     * @param format
+     * @return a string containing the converted value with the specified format.
+     */
+    public String toStringFormat(T value, String format) {
+        return toString(value);
+    }
+}
diff --git a/src/org/controlsfx/control/spreadsheet/comment.png b/src/org/controlsfx/control/spreadsheet/comment.png
new file mode 100644
index 0000000000000000000000000000000000000000..974c85b3a2c677ffedde2e977ce1224c5491e16e
Binary files /dev/null and b/src/org/controlsfx/control/spreadsheet/comment.png differ
diff --git a/src/org/controlsfx/control/spreadsheet/copySpreadsheetView.png b/src/org/controlsfx/control/spreadsheet/copySpreadsheetView.png
new file mode 100644
index 0000000000000000000000000000000000000000..de6c54def339045f2f05589b2a7588582e393074
Binary files /dev/null and b/src/org/controlsfx/control/spreadsheet/copySpreadsheetView.png differ
diff --git a/src/org/controlsfx/control/spreadsheet/package-info.java b/src/org/controlsfx/control/spreadsheet/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..15373ae82641cf8e9ad408c663a7d4b3fefb233d
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * A package containing model and view related classes used by the 
+ * {@link org.controlsfx.control.spreadsheet.SpreadsheetView} control.
+ */
+package org.controlsfx.control.spreadsheet;
\ No newline at end of file
diff --git a/src/org/controlsfx/control/spreadsheet/pasteSpreadsheetView.png b/src/org/controlsfx/control/spreadsheet/pasteSpreadsheetView.png
new file mode 100644
index 0000000000000000000000000000000000000000..62286418d514b129a875e4e075dcd38ee8d13277
Binary files /dev/null and b/src/org/controlsfx/control/spreadsheet/pasteSpreadsheetView.png differ
diff --git a/src/org/controlsfx/control/spreadsheet/picker.png b/src/org/controlsfx/control/spreadsheet/picker.png
new file mode 100644
index 0000000000000000000000000000000000000000..69a1701e57f3d10dec30f6658e17e4040fd6a81e
Binary files /dev/null and b/src/org/controlsfx/control/spreadsheet/picker.png differ
diff --git a/src/org/controlsfx/control/spreadsheet/pinSpreadsheetView.png b/src/org/controlsfx/control/spreadsheet/pinSpreadsheetView.png
new file mode 100644
index 0000000000000000000000000000000000000000..6304b62b82f938fbad45fb32ef4495a818be2d1d
Binary files /dev/null and b/src/org/controlsfx/control/spreadsheet/pinSpreadsheetView.png differ
diff --git a/src/org/controlsfx/control/spreadsheet/spreadsheet.css b/src/org/controlsfx/control/spreadsheet/spreadsheet.css
new file mode 100644
index 0000000000000000000000000000000000000000..516d3954fe36e26595a753ed44ab675b5090cd81
--- /dev/null
+++ b/src/org/controlsfx/control/spreadsheet/spreadsheet.css
@@ -0,0 +1,150 @@
+.cell-spreadsheet .table-row-cell {
+    -fx-background-color: transparent;
+}
+
+/* NORMAL CELL */
+.spreadsheet-cell:filled:selected,
+.spreadsheet-cell:filled:focused:selected,
+.spreadsheet-cell:filled:focused:selected:hover {
+    -fx-background-color: #8cb1ff;
+    -fx-border-color: #a9a9a9;
+    -fx-border-width : 0.5px;
+    -fx-text-fill: -fx-selection-bar-text;
+
+}
+.spreadsheet-cell:hover,
+.spreadsheet-cell:filled:focused {
+    -fx-background-color: #988490;
+    -fx-text-fill: -fx-text-inner-color;
+    -fx-background-insets: 0, 0 0 1 0;
+}
+
+.spreadsheet-cell{
+    -fx-padding: 0 0 0 0.2em;
+    -fx-border-color: black;
+    -fx-border-width : 0.3px;
+    -fx-background-color: -fx-table-cell-border-color,white;
+}
+
+.tooltip {
+    -fx-background-radius: 0px;
+    -fx-background-color:
+        linear-gradient(#cec340, #a59c31),
+        linear-gradient(#fefefc, #e6dd71),
+        linear-gradient(#fef592, #e5d848);
+    -fx-background-insets: 0,1,2;
+    -fx-padding: 0.333333em 0.666667em 0.333333em 0.666667em; /* 4 8 4 8 */
+    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 8, 0.0 , 0 , 0 );
+    -fx-text-fill:black;
+}
+
+/* FIXED HEADERS  */
+VerticalHeader > Label.fixed{
+    -fx-background-color: -fx-box-border, lightgray;
+    -fx-font-style : italic;
+}
+
+HorizontalHeaderColumn > TableColumnHeader.column-header.table-column.fixed{
+    -fx-background-color: -fx-box-border, lightgray;
+    -fx-font-style : italic;
+}
+
+/* HORIZONTAL AND VERTICAL HEADER SELECTION */
+VerticalHeader > Label ,
+HorizontalHeaderColumn > TableColumnHeader.column-header.table-column{
+    -fx-background-color: -fx-box-border, #F3F3F3;
+    -fx-background-insets: 0, 0 1 1 0, 1 2 2 1;
+    -fx-font-weight: bold;
+    -fx-size: 2em;
+    -fx-text-fill: -fx-selection-bar-text;
+    -fx-alignment: center;
+    -fx-font-style : normal;
+}  
+
+VerticalHeader > Label.selected{
+    -fx-background-color: #8FB1E8;
+    -fx-text-fill :white;
+}
+
+HorizontalHeaderColumn > TableColumnHeader.column-header.table-column.selected,
+HorizontalHeaderColumn > TableColumnHeader.column-header.table-column.selected > Label
+{
+    -fx-background-color:#8FB1E8;
+     -fx-text-fill :white;
+}  
+
+/* HORIZONTAL HEADER VISIBILITY */
+.column-header-background.invisible { visibility: hidden; -fx-padding: -1em; }
+
+.cell-corner{
+    -fx-background-color: red;
+}
+
+.cell-corner.top-left{
+    -fx-shape : "M 0 0 L 1 0 L 0 1 z";
+}
+
+.cell-corner.top-right{
+    -fx-shape : "M 0 0 L -1 0 L 0 1 z";
+}
+
+.cell-corner.bottom-right{
+    -fx-shape : "M 0 0 L -1 0 L 0 -1 z";
+}
+
+.cell-corner.bottom-left{
+    -fx-shape : "M 0 0 L 1 0 L 0 -1 z";
+}
+
+.indicationLabel{
+    -fx-font-style : italic;
+}
+
+/* PICKERS */
+.picker-label{
+    -fx-graphic: url("picker.png"); 
+    -fx-background-color: white;
+    -fx-padding: 0 0 0 0;
+    -fx-alignment: center;
+}
+
+.picker-label:hover{
+    /*-fx-effect:dropshadow(gaussian, black, 10, 0.1, 0, 0);*/
+    -fx-cursor:hand;
+}
+
+/* We don't want to show the white background both for TextField
+and textArea. We want it to be transparent just like Excel.
+
+Also we need to shift to the left the editor a bit*/
+CellView > .text-input.text-field{
+    -fx-padding : 0 0 0 -0.2em;
+    -fx-background-color: transparent;
+}
+CellView > .text-input.text-area,
+CellView > TextArea .scroll-pane > .viewport{
+    -fx-background-color: transparent;
+}
+
+/* I shift by 3px, it's not clean but it works for normal row (24px) as it 
+centers the textArea.*/
+CellView > TextArea .scroll-pane{
+    -fx-padding : 3px 0 0 -0.15em;
+}
+
+CellView > TextArea .scroll-pane > .viewport .content{
+    -fx-padding : 0 0 0 0;
+    -fx-background-color: transparent;
+}
+/* The scrollBars must always have the same size because we may have
+really big font in the editor (48px) and the scrollBars become obese otherwise.*/
+CellView >TextArea .scroll-bar:vertical ,
+CellView >TextArea .scroll-bar:horizontal {
+    -fx-font-size : 1em;
+}
+
+.selection-rectangle{
+    -fx-fill : transparent;
+    -fx-stroke : black;
+    -fx-stroke-width : 2;
+}
diff --git a/src/org/controlsfx/control/statusbar.css b/src/org/controlsfx/control/statusbar.css
new file mode 100644
index 0000000000000000000000000000000000000000..09f669d64a430b5db433814f0632be1402a0e7c8
--- /dev/null
+++ b/src/org/controlsfx/control/statusbar.css
@@ -0,0 +1,6 @@
+.status-bar {
+	-fx-padding: 4px;
+	-fx-pref-height: 30px;
+	-fx-background-color: lightgray, -fx-body-color;
+	-fx-background-insets: 0, 1
+}
diff --git a/src/org/controlsfx/control/table/TableFilter.java b/src/org/controlsfx/control/table/TableFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..f2672cc9d1dfbf71839156ef1c96811801a43d8a
--- /dev/null
+++ b/src/org/controlsfx/control/table/TableFilter.java
@@ -0,0 +1,225 @@
+/**
+ * Copyright (c) 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.table;
+
+import impl.org.controlsfx.table.ColumnFilter;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.collections.transformation.FilteredList;
+import javafx.collections.transformation.SortedList;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+
+import java.util.Optional;
+import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
+import java.util.stream.*;
+
+/**Applies a filtering control to a provided {@link TableView} instance. 
+ * The filter will be applied immediately on construction, and 
+ * can be made visible by right-clicking the desired column to filter on. 
+ *<br><br>
+ *<b>Features</b><br>
+ *-Convenient filter control holds a checklist of distinct items to include/exclude, much like an Excel filter.<br>
+ *-New/removed records will be captured by the filter control and reflect new or removed values from checklist.
+ *-Filters on more than one column are combined to only display mutually inclusive records on the client's TableView.
+ * @param <T>
+ */
+public final class TableFilter<T> {
+    
+    private final TableView<T> tableView;
+    private final ObservableList<T> backingList;
+    private final FilteredList<T> filteredList;
+
+    private final ObservableList<ColumnFilter<T,?>> columnFilters = FXCollections.observableArrayList();
+
+
+    /**
+     * Use TableFilter.forTableView() factory and leverage Builder
+     */
+    @Deprecated
+    public TableFilter(TableView<T> tableView) {
+        this(tableView,false);
+    }
+
+    private TableFilter(TableView<T> tableView, boolean isLazy) {
+        this.tableView = tableView;
+        backingList = tableView.getItems();
+        filteredList = new FilteredList<>(new SortedList<>(backingList));
+        SortedList<T> sortedControlList = new SortedList<>(this.filteredList);
+
+        filteredList.setPredicate(v -> true);
+
+        sortedControlList.comparatorProperty().bind(tableView.comparatorProperty());
+        tableView.setItems(sortedControlList);
+
+        applyForAllColumns(isLazy);
+        tableView.getStylesheets().add("/impl/org/controlsfx/table/tablefilter.css");
+
+        if (!isLazy) {
+            columnFilters.forEach(ColumnFilter::initialize);
+        }
+    }
+
+    /**
+     * Allows specifying a different behavior for the search box on the TableFilter.
+     * By default, the contains() method on a String is used to evaluate the search box input to qualify the distinct filter values.
+     * But you can specify a different behavior by providing a simple BiPredicate argument to this method.
+     * The BiPredicate argument allows you take the input value and target value and use a lambda to evaluate a boolean.
+     * For instance, you can implement a comparison by assuming the input value is a regular expression, and call matches()
+     * on the target value to see if it aligns to the pattern.
+     * @param searchStrategy
+     */
+    public void setSearchStrategy(BiPredicate<String,String> searchStrategy) {
+        columnFilters.forEach(cf -> cf.setSearchStrategy(searchStrategy));
+    }
+    /**
+     * Returns the backing {@link ObservableList} originally provided to the constructor.
+     * @return ObservableList
+     */
+    public ObservableList<T> getBackingList() { 
+        return backingList;
+    }
+    /**
+     * Returns the {@link FilteredList} used by this TableFilter and is backing the {@link TableView}. 
+     * @return FilteredList
+     */
+    public FilteredList<T> getFilteredList() { 
+        return filteredList;
+    }
+    /** 
+     * @treatAsPrivate
+     */
+    private void applyForAllColumns(boolean isLazy) {
+        columnFilters.setAll(tableView.getColumns().stream().flatMap(this::extractNestedColumns)
+                .map(c -> new ColumnFilter<>(this, c)).collect(Collectors.toList()));
+    }
+    private <S> Stream<TableColumn<T,?>> extractNestedColumns(TableColumn<T,S> tableColumn) {
+        if (tableColumn.getColumns().size() == 0) {
+            return Stream.of(tableColumn);
+        } else {
+            return tableColumn.getColumns().stream().flatMap(this::extractNestedColumns);
+        }
+    }
+
+    /**
+     * Programmatically selects value for the specified TableColumn
+     */
+    public void selectValue(TableColumn<?,?> column, Object value) {
+        columnFilters.stream().filter(c -> c.getTableColumn() == column)
+                .forEach(c -> c.selectValue(value));
+    }
+    /**
+     * Programmatically unselects value for the specified TableColumn
+     */
+    public void unselectValue(TableColumn<?,?> column, Object value) {
+        columnFilters.stream().filter(c -> c.getTableColumn() == column)
+                .forEach(c -> c.unselectValue(value));
+    }
+
+    /**
+     * Programmatically selects all values for the specified TableColumn
+
+     */
+    public void selectAllValues(TableColumn<?,?> column) {
+        columnFilters.stream().filter(c -> c.getTableColumn() == column)
+                .forEach(ColumnFilter::selectAllValues);
+    }
+
+    /**
+     * Programmatically unselect all values for the specified TableColumn
+     */
+    public void unSelectAllValues(TableColumn<?,?> column) {
+        columnFilters.stream().filter(c -> c.getTableColumn() == column)
+                .forEach(ColumnFilter::unSelectAllValues);
+    }
+    public void executeFilter() {
+        if (columnFilters.stream().filter(ColumnFilter::isFiltered).findAny().isPresent()) {
+            filteredList.setPredicate(item -> !columnFilters.stream()
+                    .filter(cf -> !cf.evaluate(item))
+                    .findAny().isPresent());
+        }
+        else {
+            resetFilter();
+        }
+    }
+    public void resetFilter() {
+        filteredList.setPredicate(item -> true);
+    }
+    /** 
+     * @treatAsPrivate
+     */
+    public TableView<T> getTableView() {
+        return tableView;
+    }
+    /** 
+     * @treatAsPrivate
+     */
+    public ObservableList<ColumnFilter<T,?>> getColumnFilters() {
+        return columnFilters;
+    }
+    /** 
+     * @treatAsPrivate
+     */
+    public Optional<ColumnFilter<T,?>> getColumnFilter(TableColumn<T,?> tableColumn) {
+        return columnFilters.stream().filter(f -> f.getTableColumn().equals(tableColumn)).findAny();
+    }
+    public boolean isDirty() {
+        return columnFilters.stream().filter(ColumnFilter::isFiltered).findAny().isPresent();
+    }
+
+    /**
+     * Returns a TableFilter.Builder to configure a TableFilter on the specified TableView. Call apply() to initialize and return the TableFilter
+     * @param tableView
+     * @param <T>
+     */
+    public static <T> Builder<T> forTableView(TableView<T> tableView) {
+        return new Builder<T>(tableView);
+    }
+
+    /**
+     * A Builder for a TableFilter against a specified TableView
+     * @param <T>
+     */
+    public static final class Builder<T> {
+
+        private final TableView<T> tableView;
+        private volatile boolean lazyInd = false;
+
+        private Builder(TableView<T> tableView) {
+            this.tableView = tableView;
+        }
+        public Builder<T> lazy(boolean isLazy) {
+            this.lazyInd = isLazy;
+            return this;
+        }
+        public TableFilter<T> apply() {
+            return new TableFilter<>(tableView, lazyInd);
+        }
+    }
+    
+}
diff --git a/src/org/controlsfx/control/table/TableRowExpanderColumn.java b/src/org/controlsfx/control/table/TableRowExpanderColumn.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7af39f2a230372552127e32cf5698085d019e82
--- /dev/null
+++ b/src/org/controlsfx/control/table/TableRowExpanderColumn.java
@@ -0,0 +1,325 @@
+/**
+ * Copyright (c) 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.table;
+
+import impl.org.controlsfx.skin.ExpandableTableRowSkin;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.geometry.Insets;
+import javafx.scene.Node;
+import javafx.scene.control.*;
+import javafx.util.Callback;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The TableRowExpanderColumn enables a TableView to provide an expandable editor below each table row.
+ * The column itself contains a toggle button that on click will show an editor for the current row right below the
+ * columns. Example:
+ *
+ * <pre>
+ * TableRowExpanderColumn&lt;Customer> expander = new TableRowExpanderColumn&lt;>(param -> {
+ *     HBox editor = new HBox(10);
+ *     TextField text = new TextField(param.getValue().getName());
+ *     Button save = new Button("Save customer");
+ *     save.setOnAction(event -> {
+ *         save();
+ *         param.toggleExpanded();
+ *     });
+ *     editor.getChildren().addAll(text, save);
+ *     return editor;
+ * });
+ *
+ * tableView.getColumns().add(expander);
+ * </pre>
+ *
+ * You can provide a custom cellFactory to customize the toggle button. A typical custom toggle cell implementation
+ * would look like this:
+ *
+ * <pre>
+ * public class MyCustomToggleCell&lt;S> extends TableCell&lt;S, Boolean> {
+ *     private Button button = new Button();
+ *
+ *     public MyCustomToggleCell(TableRowExpanderColumn&lt;S> column) {
+ *         button.setOnAction(event -> column.toggleExpanded(getIndex()));
+ *     }
+ *
+ *     protected void updateItem(Boolean expanded, boolean empty) {
+ *         super.updateItem(expanded, empty);
+ *         if (expanded == null || empty) {
+ *             setGraphic(null);
+ *         } else {
+ *             button.setText(expanded ? "Collapse" : "Expand");
+ *             setGraphic(button);
+ *         }
+ *     }
+ * }
+ * </pre>
+ *
+ * The custom toggle cell utilizes the {@link TableRowExpanderColumn#toggleExpanded(int)} method to toggle
+ * the row expander instead of param.toggleExpanded() like the editor does.
+ *
+ * @param <S> The item type of the TableView
+ */
+public final class TableRowExpanderColumn<S> extends TableColumn<S, Boolean> {
+    private static final String STYLE_CLASS = "expander-column";
+    private static final String EXPANDER_BUTTON_STYLE_CLASS = "expander-button";
+
+    private final Map<S, Node> expandedNodeCache = new HashMap<>();
+    private final Map<S, BooleanProperty> expansionState = new HashMap<>();
+    private Callback<TableRowDataFeatures<S>, Node> expandedNodeCallback;
+
+    /**
+     * Returns a Boolean property that can be used to manipulate the expanded state for a row
+     * corresponding to the given item value.
+     *
+     * @param item The item corresponding to a table row
+     * @return The boolean property
+     */
+    public BooleanProperty getExpandedProperty(S item) {
+        BooleanProperty value = expansionState.get(item);
+        if (value == null) {
+            value = new SimpleBooleanProperty(item, "expanded", false) {
+                /**
+                 * When the expanded state change we refresh the tableview.
+                 * If the expanded state changes to false we remove the cached expanded node.
+                 */
+                @Override
+                protected void invalidated() {
+                    getTableView().refresh();
+                    if (!getValue()) expandedNodeCache.remove(getBean());
+                }
+            };
+            expansionState.put(item, value);
+        }
+        return value;
+    }
+
+    /**
+     * Get or create and cache the expanded node for a given item.
+     *
+     * @param tableRow The table row, used to find the item index
+     * @return The expanded node for the given item
+     */
+    public Node getOrCreateExpandedNode(TableRow<S> tableRow) {
+        int index = tableRow.getIndex();
+        if (index > -1 && index < getTableView().getItems().size()) {
+            S item = getTableView().getItems().get(index);
+            Node node = expandedNodeCache.get(item);
+            if (node == null) {
+                node = expandedNodeCallback.call(new TableRowDataFeatures<>(tableRow, this, item));
+                expandedNodeCache.put(item, node);
+            }
+            return node;
+        }
+        return null;
+    }
+
+    /**
+     * Return the expanded node for the given item, if it exists.
+     *
+     * @param item The item corresponding to a table row
+     * @return The expanded node, if it exists.
+     */
+    public Node getExpandedNode(S item) {
+        return expandedNodeCache.get(item);
+    }
+
+    /**
+     * Create a row expander column that can be added to the TableView list of columns.
+     *
+     * The expandedNodeCallback is expected to return a Node representing the editor that should appear below the
+     * table row when the toggle button within the expander column is clicked.
+     *
+     * Once this column is assigned to a TableView, it will automatically install a custom row factory for the TableView
+     * so that it can configure a TableRow with the {@link impl.org.controlsfx.skin.ExpandableTableRowSkin}. It is within the skin that the actual
+     * rendering of the expanded node occurs.
+     *
+     * @see TableRowExpanderColumn
+     * @see TableRowDataFeatures
+     *
+     * @param expandedNodeCallback
+     */
+    public TableRowExpanderColumn(Callback<TableRowDataFeatures<S>, Node> expandedNodeCallback) {
+        this.expandedNodeCallback = expandedNodeCallback;
+
+        getStyleClass().add(STYLE_CLASS);
+        setCellValueFactory(param -> getExpandedProperty(param.getValue()));
+        setCellFactory(param -> new ToggleCell());
+        installRowFactoryOnTableViewAssignment();
+    }
+
+    /**
+     * Install the row factory on the TableView when this column is assigned to a TableView.
+     */
+    private void installRowFactoryOnTableViewAssignment() {
+        tableViewProperty().addListener((observable, oldValue, newValue) -> {
+            if (newValue != null) {
+                getTableView().setRowFactory(param -> new TableRow<S>() {
+                    @Override
+                    protected Skin<?> createDefaultSkin() {
+                        return new ExpandableTableRowSkin<>(this, TableRowExpanderColumn.this);
+                    }
+                });
+            }
+        });
+    }
+
+    /**
+     * The default toggle cell creates a button with a + or - sign as the text,
+     * depending on the expanded state of the row it represents.
+     *
+     * You can use this as a starting point to implement a custom toggle cell.
+     */
+    private final class ToggleCell extends TableCell<S, Boolean> {
+        private Button button = new Button();
+
+        public ToggleCell() {
+            button.setFocusTraversable(false);
+            button.getStyleClass().add(EXPANDER_BUTTON_STYLE_CLASS);
+            button.setPrefSize(16, 16);
+            button.setPadding(new Insets(0));
+            button.setOnAction(event -> toggleExpanded(getIndex()));
+        }
+
+        @Override
+        protected void updateItem(Boolean expanded, boolean empty) {
+            super.updateItem(expanded, empty);
+            if (expanded == null || empty) {
+                setGraphic(null);
+            } else {
+                button.setText(expanded ? "-" : "+");
+                setGraphic(button);
+            }
+        }
+    }
+
+    /**
+     * Toggle the expanded state of the row at the given index.
+     *
+     * @param index The index of the row you want to toggle expansion for.
+     */
+    public void toggleExpanded(int index) {
+        BooleanProperty expanded = (BooleanProperty) getCellObservableValue(index);
+        expanded.setValue(!expanded.getValue());
+    }
+
+    /**
+     * This object is passed to the expanded node callback when it is time to create a Node to represent the
+     * expanded editor of a certain row. The most important method is {@link #getValue()}} which returns the
+     * object represented by the current row.
+     *
+     * Further more, the {@link #expandedProperty()} returns a boolean property indicating the current expansion
+     * state of the current row. You can use this, or the {@link #toggleExpanded()} method to toggle and inspect
+     * the expanded state of the row, for example if you want an action inside the row editor to contract the editor.
+     *
+     * @param <S> The type of items in the TableView
+     */
+    public static final class TableRowDataFeatures<S> {
+        private TableRow<S> tableRow;
+        private TableRowExpanderColumn<S> tableColumn;
+        private BooleanProperty expandedProperty;
+        private S value;
+
+        public TableRowDataFeatures(TableRow<S> tableRow, TableRowExpanderColumn<S> tableColumn, S value) {
+            this.tableRow = tableRow;
+            this.tableColumn = tableColumn;
+            this.expandedProperty = (BooleanProperty) tableColumn.getCellObservableValue(tableRow.getIndex());
+            this.value = value;
+        }
+
+        /**
+         * Return the current TableRow. It is safe to assume that the index returned by {@link TableRow#getIndex()} is
+         * correct as long as you use it for the initial node creation. It is not safe to trust the result of this call
+         * at any later time, for example in a button action within the row editor.
+         *
+         * @return The current TableRow
+         */
+        public TableRow<S> getTableRow() {
+            return tableRow;
+        }
+
+        /**
+         * Return the TableColumn which contains the toggle button. Normally you would not need to use this directly,
+         * but rather consult the {@link #expandedProperty()} for inspection and mutation of the toggled state of this row.
+         *
+         * @return The TableColumn which contains the toggle button
+         */
+        public TableRowExpanderColumn<S> getTableColumn() {
+            return tableColumn;
+        }
+
+        /**
+         * The expanded property can be used to inspect or mutate the toggled state of this row editor. You can also
+         * listen for changes to it's state if needed.
+         *
+         * @return The expanded property
+         */
+        public BooleanProperty expandedProperty() {
+            return expandedProperty;
+        }
+
+        /**
+         * Toggle the expanded state of this row editor.
+         */
+        public void toggleExpanded() {
+            BooleanProperty expanded = expandedProperty();
+            expanded.setValue(!expanded.getValue());
+        }
+
+        /**
+         * Returns a boolean indicating if the current row is expanded or not
+         *
+         * @return A boolean indicating the expanded state of the current editor
+         */
+        public Boolean isExpanded() {
+            return expandedProperty().getValue();
+        }
+
+        /**
+         * Set the expanded state. This will update the {@link #expandedProperty()} accordingly.
+         *
+         * @param expanded Wheter the row editor should be expanded or not
+         */
+        public void setExpanded(Boolean expanded) {
+            expandedProperty().setValue(expanded);
+        }
+
+        /**
+         * The value represented by the current table row. It is important that the value has valid equals/hashCode
+         * methods, as the row value is used to keep track of the node editor for each row.
+         *
+         * @return The value represented by the current table row
+         */
+        public S getValue() {
+            return value;
+        }
+
+    }
+
+}
diff --git a/src/org/controlsfx/control/table/TableViewUtils.java b/src/org/controlsfx/control/table/TableViewUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..94a020e3268bd27df729c4180803e6874c65e581
--- /dev/null
+++ b/src/org/controlsfx/control/table/TableViewUtils.java
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.table;
+
+import java.lang.reflect.Field;
+import java.util.function.Consumer;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.collections.ObservableList;
+import javafx.scene.Node;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.Control;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.Skin;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TreeTableView;
+
+import com.sun.javafx.scene.control.skin.TableHeaderRow;
+import com.sun.javafx.scene.control.skin.TableViewSkin;
+import com.sun.javafx.scene.control.skin.TableViewSkinBase;
+
+/**
+ * A utility class for API revolving around the JavaFX {@link TableView} and
+ * {@link TreeTableView} controls.
+ */
+// not public as not ready for 8.20.7
+final class TableViewUtils {
+
+    /**
+     * Call this method to be able to programatically manipulate the 
+     * {@link TableView#tableMenuButtonVisibleProperty() TableView menu button}
+     * (assuming it is visible). This allows developers to, for example, add in
+     * new {@link MenuItem}.
+     */
+    public static void modifyTableMenu(final TableView<?> tableView, final Consumer<ContextMenu> consumer) {
+        modifyTableMenu((Control)tableView, consumer);
+    }
+    
+    /**
+     * Call this method to be able to programatically manipulate the 
+     * {@link TreeTableView#tableMenuButtonVisibleProperty() TreeTableView menu button}
+     * (assuming it is visible). This allows developers to, for example, add in
+     * new {@link MenuItem}.
+     */
+    public static void modifyTableMenu(final TreeTableView<?> treeTableView, final Consumer<ContextMenu> consumer) {
+        modifyTableMenu((Control)treeTableView, consumer);
+    }
+    
+    private static void modifyTableMenu(final Control control, final Consumer<ContextMenu> consumer) {
+        if (control.getScene() == null) {
+            control.sceneProperty().addListener(new InvalidationListener() {
+                @Override public void invalidated(Observable o) {
+                    control.sceneProperty().removeListener(this);
+                    modifyTableMenu(control, consumer);
+                }
+            });
+            
+            return;
+        }
+        
+        Skin<?> skin = control.getSkin();
+        if (skin == null) {
+            control.skinProperty().addListener(new InvalidationListener() {
+                @Override public void invalidated(Observable o) {
+                    control.skinProperty().removeListener(this);
+                    modifyTableMenu(control, consumer);
+                }
+            });
+            
+            return;
+        }
+
+        doModify(skin, consumer);
+    }
+
+    private static void doModify(Skin<?> skin, Consumer<ContextMenu> consumer) {
+        if (! (skin instanceof TableViewSkinBase)) return;
+
+        TableViewSkin<?> tableSkin = (TableViewSkin<?>)skin;
+        TableHeaderRow headerRow = getHeaderRow(tableSkin);
+        if (headerRow == null) return;
+
+        ContextMenu contextMenu = getContextMenu(headerRow);
+        consumer.accept(contextMenu);        
+    }
+
+    private static TableHeaderRow getHeaderRow(TableViewSkin<?> tableSkin) {
+        ObservableList<Node> children = tableSkin.getChildren();
+        for (int i = 0, max = children.size(); i < max; i++) {
+            Node child = children.get(i);
+            if (child instanceof TableHeaderRow) return (TableHeaderRow) child;
+        }
+        return null;
+    }
+
+    private static ContextMenu getContextMenu(TableHeaderRow headerRow) {
+        try {
+            Field privateContextMenuField = TableHeaderRow.class.getDeclaredField("columnPopupMenu"); //$NON-NLS-1$
+            privateContextMenuField.setAccessible(true);
+            ContextMenu contextMenu = (ContextMenu) privateContextMenuField.get(headerRow);
+            return contextMenu;
+        } catch (IllegalArgumentException ex) {
+            ex.printStackTrace();
+        } catch (IllegalAccessException ex) {
+            ex.printStackTrace();
+        } catch (NoSuchFieldException ex) {
+            ex.printStackTrace();
+        } catch (SecurityException ex) {
+            ex.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/src/org/controlsfx/control/table/model/JavaFXTableModel.java b/src/org/controlsfx/control/table/model/JavaFXTableModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..b59512342bf242a60e0d6f00e27333199e9e62fb
--- /dev/null
+++ b/src/org/controlsfx/control/table/model/JavaFXTableModel.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.table.model;
+
+import javafx.scene.control.TableView;
+
+/**
+ *
+ */
+//not public as not ready for 8.20.7
+interface JavaFXTableModel<T> {
+    public T getValueAt(int rowIndex, int columnIndex);
+    
+    public void setValueAt(T value, int rowIndex, int columnIndex);
+    
+    public int getRowCount();
+    
+    public int getColumnCount();
+    
+    public String getColumnName(int columnIndex);
+    
+    public void sort(TableView<TableModelRow<T>> table);
+}
diff --git a/src/org/controlsfx/control/table/model/JavaFXTableModels.java b/src/org/controlsfx/control/table/model/JavaFXTableModels.java
new file mode 100644
index 0000000000000000000000000000000000000000..734e123a210f6626ed5d4f58706aec79c3795e8a
--- /dev/null
+++ b/src/org/controlsfx/control/table/model/JavaFXTableModels.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.table.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumn.SortType;
+import javafx.scene.control.TableView;
+
+import javax.swing.RowSorter.SortKey;
+import javax.swing.SortOrder;
+import javax.swing.table.TableModel;
+import javax.swing.table.TableRowSorter;
+
+/**
+ *
+ */
+//not public as not ready for 8.20.7
+class JavaFXTableModels {
+    
+    /**
+     * Swing
+     */
+    public static <S> JavaFXTableModel<S> wrap(final TableModel tableModel) {
+        
+        return new JavaFXTableModel<S>() {
+            final TableRowSorter<TableModel> sorter;
+            
+            {
+                sorter = new TableRowSorter<>(tableModel);
+            }
+            
+            @SuppressWarnings("unchecked")
+            @Override public S getValueAt(int rowIndex, int columnIndex) {
+                return (S) tableModel.getValueAt(sorter.convertRowIndexToView(rowIndex), columnIndex);
+            }
+
+            @Override public void setValueAt(S value, int rowIndex, int columnIndex) {
+                tableModel.setValueAt(value, rowIndex, columnIndex);
+            }
+
+            @Override public int getRowCount() {
+                return tableModel.getRowCount();
+            }
+
+            @Override public int getColumnCount() {
+                return tableModel.getColumnCount();
+            }
+
+            @Override public String getColumnName(int columnIndex) {
+                return tableModel.getColumnName(columnIndex);
+            }
+            
+            @Override public void sort(TableView<TableModelRow<S>> table) {
+                List<SortKey> sortKeys = new ArrayList<>();
+                
+                for (TableColumn<TableModelRow<S>, ?> column : table.getSortOrder()) {
+                    final int columnIndex = table.getVisibleLeafIndex(column);
+                    final SortType sortType = column.getSortType();
+                    SortOrder sortOrder = sortType == SortType.ASCENDING ? SortOrder.ASCENDING :
+                                          sortType == SortType.DESCENDING ? SortOrder.DESCENDING :
+                                          SortOrder.UNSORTED;
+                    SortKey sortKey = new SortKey(columnIndex, sortOrder);
+                    sortKeys.add(sortKey);
+                    
+                    sorter.setComparator(columnIndex, column.getComparator());
+                }
+                
+                sorter.setSortKeys(sortKeys);
+                sorter.sort();
+            }
+        };
+    }
+}
diff --git a/src/org/controlsfx/control/table/model/TableModelRow.java b/src/org/controlsfx/control/table/model/TableModelRow.java
new file mode 100644
index 0000000000000000000000000000000000000000..0eaa638e19180ef5cfe3fc001f893cc2e51fa9f1
--- /dev/null
+++ b/src/org/controlsfx/control/table/model/TableModelRow.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.table.model;
+
+/**
+ */
+class TableModelRow<S> {
+    private final int columnCount;
+    private final JavaFXTableModel<S> tableModel;
+    private final int row;
+
+    TableModelRow(JavaFXTableModel<S> tableModel, int row) {
+        this.row = row;
+        this.tableModel = tableModel;
+        this.columnCount = tableModel.getColumnCount();
+    }
+    
+    public Object get(int column) {
+        return column < 0 || column >= columnCount ? null : this.tableModel.getValueAt(row, column);
+    }
+
+    @Override public String toString() {
+        String text = "Row " + row + ": [ "; //$NON-NLS-1$ //$NON-NLS-2$
+        
+        for (int col = 0; col < columnCount; col++) {
+            text += get(col);
+            
+            if (col < (columnCount - 1)) {
+                text += ", "; //$NON-NLS-1$
+            }
+        }
+        
+        text += " ]"; //$NON-NLS-1$
+        return text;
+    }
+}
diff --git a/src/org/controlsfx/control/table/model/TableModelTableView.java b/src/org/controlsfx/control/table/model/TableModelTableView.java
new file mode 100644
index 0000000000000000000000000000000000000000..596a8d5c03750732b9d829566db25e19833353ca
--- /dev/null
+++ b/src/org/controlsfx/control/table/model/TableModelTableView.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.table.model;
+
+import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+
+/**
+ *
+ */
+//not public as not ready for 8.20.7
+class TableModelTableView<S> extends TableView<TableModelRow<S>> {
+
+    public TableModelTableView(final JavaFXTableModel<S> tableModel) {
+        // create a dummy items list of the appropriate size, where the returned
+        // value is the index of the row
+        setItems(new ReadOnlyUnbackedObservableList<TableModelRow<S>>() {
+            @Override public TableModelRow<S> get(int row) {
+                if (row < 0 || row >= tableModel.getRowCount()) return null;
+                TableModelRow<S> backingRow = new TableModelRow<>(tableModel, row);
+                return backingRow;
+            }
+
+            @Override public int size() {
+                return tableModel.getRowCount();
+            }
+        });
+        
+        setSortPolicy(table -> {
+            tableModel.sort(table);
+            return true;
+        });
+        
+        // create columns from the table model
+        for (int i = 0; i < tableModel.getColumnCount(); i++) {
+            TableColumn<TableModelRow<S>,?> column = new TableColumn<>(tableModel.getColumnName(i));
+            column.setCellValueFactory(new TableModelValueFactory<>(tableModel, i));
+            getColumns().add(column);
+        }
+    }
+}
diff --git a/src/org/controlsfx/control/table/model/TableModelValueFactory.java b/src/org/controlsfx/control/table/model/TableModelValueFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..bc098b93cbe902d011bee7ee030ac72ec1365421
--- /dev/null
+++ b/src/org/controlsfx/control/table/model/TableModelValueFactory.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.table.model;
+
+import javafx.beans.property.ReadOnlyObjectWrapper;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.TableColumn;
+import javafx.util.Callback;
+import javafx.scene.control.TableColumn.CellDataFeatures;
+
+/**
+ *
+ */
+//not public as not ready for 8.20.7
+class TableModelValueFactory<S, T> implements Callback<CellDataFeatures<TableModelRow<S>, T>, ObservableValue<T>> {
+    @SuppressWarnings("unused")
+    private final JavaFXTableModel<S> _tableModel;
+    private final int _columnIndex;
+
+    public TableModelValueFactory(JavaFXTableModel<S> tableModel, int columnIndex) {
+        _tableModel = tableModel;
+        _columnIndex = columnIndex;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override public ObservableValue<T> call(TableColumn.CellDataFeatures<TableModelRow<S>, T> cdf) {
+        TableModelRow<S> row = cdf.getValue();
+        T valueAt = (T) row.get(_columnIndex);
+        return valueAt instanceof ObservableValue ? ((ObservableValue<T>) valueAt) : new ReadOnlyObjectWrapper<>(valueAt);
+    }
+}
diff --git a/src/org/controlsfx/control/taskprogressview.css b/src/org/controlsfx/control/taskprogressview.css
new file mode 100644
index 0000000000000000000000000000000000000000..2c88aba4dec6cdddac7b8cf2e4307b293475d3f8
--- /dev/null
+++ b/src/org/controlsfx/control/taskprogressview.css
@@ -0,0 +1,53 @@
+
+.task-progress-view  {
+ 	-fx-background-color: white;
+}
+
+.task-progress-view > * > .label {
+ 	-fx-text-fill: gray;
+ 	-fx-font-size: 18.0;
+ 	-fx-alignment: center;
+ 	-fx-padding: 10.0 0.0 5.0 0.0;
+}
+
+.task-progress-view > * > .list-view  {
+ 	-fx-border-color: transparent;
+ 	-fx-background-color: transparent;
+}
+
+.task-title {
+	-fx-font-weight: bold;
+}
+
+.task-progress-bar .bar {
+	-fx-padding: 6px;
+	-fx-background-radius: 0;
+	-fx-border-radius: 0;
+}
+
+.task-progress-bar .track {
+	-fx-background-radius: 0;
+}
+
+.task-message {
+}
+
+.task-list-cell {
+    -fx-background-color: transparent;
+    -fx-padding: 4 10 8 10;
+    -fx-border-color: transparent transparent linear-gradient(from 0.0% 0.0% to 100.0% 100.0%, transparent, rgba(0.0,0.0,0.0,0.2), transparent) transparent;
+}
+
+.task-list-cell-empty {
+	-fx-background-color: transparent;
+    -fx-border-color: transparent;
+}
+
+.task-cancel-button {
+	-fx-base-color: red;
+	-fx-font-size: .75em;
+	-fx-font-weight: bold;
+	-fx-padding: 4px;
+	-fx-border-radius: 0;
+	-fx-background-radius: 0;
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/textfield/AutoCompletionBinding.java b/src/org/controlsfx/control/textfield/AutoCompletionBinding.java
new file mode 100644
index 0000000000000000000000000000000000000000..f851ea07d57efe8013e9b6ae37fb6ddb636240a1
--- /dev/null
+++ b/src/org/controlsfx/control/textfield/AutoCompletionBinding.java
@@ -0,0 +1,558 @@
+/**
+ * Copyright (c) 2014, 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.textfield;
+
+import com.sun.javafx.event.EventHandlerManager;
+import impl.org.controlsfx.skin.AutoCompletePopup;
+import impl.org.controlsfx.skin.AutoCompletePopupSkin;
+import javafx.application.Platform;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ObjectPropertyBase;
+import javafx.concurrent.Task;
+import javafx.event.*;
+import javafx.scene.Node;
+import javafx.scene.control.ListView;
+import javafx.scene.control.Skin;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+
+import java.util.Collection;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.IntegerProperty;
+
+/**
+ * The AutoCompletionBinding is the abstract base class of all auto-completion bindings.
+ * This class is the core logic for the auto-completion feature but highly customizable.
+ * 
+ * <p>To use the autocompletion functionality, refer to the {@link TextFields} class.
+ *
+ * The popup size can be modified through its {@link #setVisibleRowCount(int) }
+ * for the height and all the usual methods for the width.
+ * 
+ * @param <T> Model-Type of the suggestions
+ * @see TextFields
+ */
+public abstract class AutoCompletionBinding<T> implements EventTarget {
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Private fields                                                          *
+     *                                                                         *
+     **************************************************************************/
+    private final Node completionTarget;
+    private final AutoCompletePopup<T> autoCompletionPopup;
+    private final Object suggestionsTaskLock = new Object();
+
+    private FetchSuggestionsTask suggestionsTask = null;
+    private Callback<ISuggestionRequest, Collection<T>> suggestionProvider = null;
+    private boolean ignoreInputChanges = false;
+    private long delay = 250;
+
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+
+    /**
+     * Creates a new AutoCompletionBinding
+     * 
+     * @param completionTarget The target node to which auto-completion shall be added
+     * @param suggestionProvider The strategy to retrieve suggestions 
+     * @param converter The converter to be used to convert suggestions to strings 
+     */
+    protected AutoCompletionBinding(Node completionTarget, 
+            Callback<ISuggestionRequest, Collection<T>> suggestionProvider,
+            StringConverter<T> converter){
+
+        this.completionTarget = completionTarget;
+        this.suggestionProvider = suggestionProvider;
+        this.autoCompletionPopup = new AutoCompletePopup<>();
+        this.autoCompletionPopup.setConverter(converter);
+
+        autoCompletionPopup.setOnSuggestion(sce -> {
+            try{
+                setIgnoreInputChanges(true);
+                completeUserInput(sce.getSuggestion());
+                fireAutoCompletion(sce.getSuggestion());
+                hidePopup();
+            }finally{
+                // Ensure that ignore is always set back to false
+                setIgnoreInputChanges(false);
+            }
+        });
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Specifies whether the PopupWindow should be hidden when an unhandled
+     * escape key is pressed while the popup has focus.
+     *
+     * @param value
+     */
+    public void setHideOnEscape(boolean value) {
+        autoCompletionPopup.setHideOnEscape(value);
+    }
+
+    /**
+     * Set the current text the user has entered
+     * @param userText
+     */
+    public final void setUserInput(String userText){
+        if(!isIgnoreInputChanges()){
+            onUserInputChanged(userText);
+        }
+    }
+
+    /**
+     * Sets the delay in ms between a key press and the suggestion popup being displayed.
+     *
+     * @param delay
+     */
+    public final void setDelay(long delay) {
+        this.delay = delay;
+    }
+
+    /**
+     * Gets the target node for auto completion
+     * @return the target node for auto completion
+     */
+    public Node getCompletionTarget(){
+        return completionTarget;
+    }
+
+    /**
+     * Disposes the binding.
+     */
+    public abstract void dispose();
+
+
+    /**
+     * Set the maximum number of rows to be visible in the popup when it is
+     * showing.
+     *
+     * @param value
+     */
+    public final void setVisibleRowCount(int value) {
+        autoCompletionPopup.setVisibleRowCount(value);
+    }
+
+    /**
+     * Return the maximum number of rows to be visible in the popup when it is
+     * showing.
+     *
+     * @return the maximum number of rows to be visible in the popup when it is
+     * showing.
+     */
+    public final int getVisibleRowCount() {
+        return autoCompletionPopup.getVisibleRowCount();
+    }
+
+    /**
+     * Return an property representing the maximum number of rows to be visible
+     * in the popup when it is showing.
+     *
+     * @return an property representing the maximum number of rows to be visible
+     * in the popup when it is showing.
+     */
+    public final IntegerProperty visibleRowCountProperty() {
+        return autoCompletionPopup.visibleRowCountProperty();
+    }
+    
+    /**
+     * Sets the prefWidth of the popup.
+     *
+     * @param value
+     */
+    public final void setPrefWidth(double value) {
+        autoCompletionPopup.setPrefWidth(value);
+    }
+
+    /**
+     * Return the pref width of the popup.
+     *
+     * @return the pref width of the popup.
+     */
+    public final double getPrefWidth() {
+        return autoCompletionPopup.getPrefWidth();
+    }
+
+    /**
+     * Return the property associated with the pref width.
+     * @return 
+     */
+    public final DoubleProperty prefWidthProperty() {
+        return autoCompletionPopup.prefWidthProperty();
+    }
+
+    /**
+     * Sets the minWidth of the popup.
+     *
+     * @param value
+     */
+    public final void setMinWidth(double value) {
+        autoCompletionPopup.setMinWidth(value);
+    }
+
+    /**
+     * Return the min width of the popup.
+     *
+     * @return the min width of the popup.
+     */
+    public final double getMinWidth() {
+        return autoCompletionPopup.getMinWidth();
+    }
+
+    /**
+     * Return the property associated with the min width.
+     * @return 
+     */
+    public final DoubleProperty minWidthProperty() {
+        return autoCompletionPopup.minWidthProperty();
+    }
+
+    /**
+     * Sets the maxWidth of the popup.
+     *
+     * @param value
+     */
+    public final void setMaxWidth(double value) {
+        autoCompletionPopup.setMaxWidth(value);
+    }
+
+    /**
+     * Return the max width of the popup.
+     *
+     * @return the max width of the popup.
+     */
+    public final double getMaxWidth() {
+        return autoCompletionPopup.getMaxWidth();
+    }
+
+    /**
+     * Return the property associated with the max width.
+     * @return 
+     */
+    public final DoubleProperty maxWidthProperty() {
+        return autoCompletionPopup.maxWidthProperty();
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Protected methods                                                       *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Complete the current user-input with the provided completion.
+     * Sub-classes have to provide a concrete implementation.
+     * @param completion
+     */
+    protected abstract void completeUserInput(T completion);
+
+
+    /**
+     * Show the auto completion popup
+     */
+    protected void showPopup(){
+        autoCompletionPopup.show(completionTarget);
+        selectFirstSuggestion(autoCompletionPopup);
+    }
+
+    /**
+     * Hide the auto completion targets
+     */
+    protected void hidePopup(){
+        autoCompletionPopup.hide();
+    }
+
+    protected void fireAutoCompletion(T completion){
+        Event.fireEvent(this, new AutoCompletionEvent<>(completion));
+    }
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Private methods                                                         *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Selects the first suggestion (if any), so the user can choose it
+     * by pressing enter immediately.
+     */
+    private void selectFirstSuggestion(AutoCompletePopup<?> autoCompletionPopup){
+        Skin<?> skin = autoCompletionPopup.getSkin();
+        if(skin instanceof AutoCompletePopupSkin){
+            AutoCompletePopupSkin<?> au = (AutoCompletePopupSkin<?>)skin;
+            ListView<?> li = (ListView<?>)au.getNode();
+            if(li.getItems() != null && !li.getItems().isEmpty()){
+                li.getSelectionModel().select(0);
+            }
+        }
+    }
+
+    /**
+     * Occurs when the user text has changed and the suggestions require an update
+     * @param userText
+     */
+    private final void onUserInputChanged(final String userText){
+        synchronized (suggestionsTaskLock) {
+            if(suggestionsTask != null && suggestionsTask.isRunning()){
+                // cancel the current running task
+                suggestionsTask.cancel(); 
+            }
+            // create a new fetcher task
+            suggestionsTask = new FetchSuggestionsTask(userText, delay);
+            new Thread(suggestionsTask).start();
+        }
+    }
+
+    /**
+     * Shall changes to the user input be ignored?
+     * @return
+     */
+    private boolean isIgnoreInputChanges(){
+        return ignoreInputChanges;
+    }
+
+    /**
+     * If IgnoreInputChanges is set to true, all changes to the user input are
+     * ignored. This is primary used to avoid self triggering while
+     * auto completing.
+     * @param state
+     */
+    private void setIgnoreInputChanges(boolean state){
+        ignoreInputChanges = state;
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Inner classes and interfaces                                            *
+     *                                                                         *
+     **************************************************************************/
+
+
+    /**
+     * Represents a suggestion fetch request
+     *
+     */
+    public static interface ISuggestionRequest {
+        /**
+         * Is this request canceled?
+         * @return {@code true} if the request is canceled, otherwise {@code false}
+         */
+        public boolean isCancelled();
+
+        /**
+         * Get the user text to which suggestions shall be found
+         * @return {@link String} containing the user text
+         */
+        public String getUserText();
+    }
+
+
+
+    /**
+     * This task is responsible to fetch suggestions asynchronous
+     * by using the current defined suggestionProvider
+     *
+     */
+    private class FetchSuggestionsTask extends Task<Void> implements ISuggestionRequest {
+        private final String userText;
+        private final long delay;
+
+        public FetchSuggestionsTask(String userText, long delay){
+            this.userText = userText;
+            this.delay = delay;
+        }
+
+        @Override
+        protected Void call() throws Exception {
+            Callback<ISuggestionRequest, Collection<T>> provider = suggestionProvider;
+            if(provider != null){
+            	long startTime = System.currentTimeMillis();
+                final Collection<T> fetchedSuggestions = provider.call(this);
+                long sleepTime = startTime + delay - System.currentTimeMillis();
+                if (sleepTime > 0 && !isCancelled()) {
+                	Thread.sleep(sleepTime);
+                }
+                if(!isCancelled()){
+                    Platform.runLater(() -> {
+                        if(fetchedSuggestions != null && !fetchedSuggestions.isEmpty()){
+                            autoCompletionPopup.getSuggestions().setAll(fetchedSuggestions);
+                            showPopup();
+                        }else{
+                            // No suggestions found, so hide the popup
+                            hidePopup();
+                        }
+                    });
+                }
+            }else {
+                // No suggestion provider
+                hidePopup();
+            }
+            return null;
+        }
+
+        @Override
+        public String getUserText() {
+            return userText;
+        }
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Events                                                                  *
+     *                                                                         *
+     **************************************************************************/
+
+
+    // --- AutoCompletionEvent
+
+    /**
+     * Represents an Event which is fired after an auto completion.
+     */
+    @SuppressWarnings("serial")
+    public static class AutoCompletionEvent<TE> extends Event {
+
+        /**
+         * The event type that should be listened to by people interested in 
+         * knowing when an auto completion has been performed.
+         */
+        @SuppressWarnings("rawtypes")
+        public static final EventType<AutoCompletionEvent> AUTO_COMPLETED = new EventType<>("AUTO_COMPLETED"); //$NON-NLS-1$
+
+        private final TE completion;
+
+        /**
+         * Creates a new event that can subsequently be fired.
+         */
+        public AutoCompletionEvent(TE completion) {
+            super(AUTO_COMPLETED);
+            this.completion = completion;
+        }
+
+        /**
+         * Returns the chosen completion.
+         */
+        public TE getCompletion() {
+            return completion;
+        }
+    }
+
+
+    private ObjectProperty<EventHandler<AutoCompletionEvent<T>>> onAutoCompleted;
+
+    /**
+     * Set a event handler which is invoked after an auto completion.
+     * @param value
+     */
+    public final void setOnAutoCompleted(EventHandler<AutoCompletionEvent<T>> value) {
+        onAutoCompletedProperty().set( value);
+    }
+
+    public final EventHandler<AutoCompletionEvent<T>> getOnAutoCompleted() {
+        return onAutoCompleted == null ? null : onAutoCompleted.get();
+    }
+
+    public final ObjectProperty<EventHandler<AutoCompletionEvent<T>>> onAutoCompletedProperty() {
+        if (onAutoCompleted == null) {
+            onAutoCompleted = new ObjectPropertyBase<EventHandler<AutoCompletionEvent<T>>>() {
+                @SuppressWarnings({ "rawtypes", "unchecked" })
+                @Override protected void invalidated() {
+                    eventHandlerManager.setEventHandler(
+                            AutoCompletionEvent.AUTO_COMPLETED,
+                            (EventHandler<AutoCompletionEvent>)(Object)get());
+                }
+
+                @Override
+                public Object getBean() {
+                    return AutoCompletionBinding.this;
+                }
+
+                @Override
+                public String getName() {
+                    return "onAutoCompleted"; //$NON-NLS-1$
+                }
+            };
+        }
+        return onAutoCompleted;
+    }
+
+
+    /***************************************************************************
+     *                                                                         *
+     * EventTarget Implementation                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    final EventHandlerManager eventHandlerManager = new EventHandlerManager(this);
+
+    /**
+     * Registers an event handler to this EventTarget. The handler is called when the
+     * menu item receives an {@code Event} of the specified type during the bubbling
+     * phase of event delivery.
+     *
+     * @param <E> the specific event class of the handler
+     * @param eventType the type of the events to receive by the handler
+     * @param eventHandler the handler to register
+     * @throws NullPointerException if the event type or handler is null
+     */
+    public <E extends Event> void addEventHandler(EventType<E> eventType, EventHandler<E> eventHandler) {
+        eventHandlerManager.addEventHandler(eventType, eventHandler);
+    }
+
+    /**
+     * Unregisters a previously registered event handler from this EventTarget. One
+     * handler might have been registered for different event types, so the
+     * caller needs to specify the particular event type from which to
+     * unregister the handler.
+     *
+     * @param <E> the specific event class of the handler
+     * @param eventType the event type from which to unregister
+     * @param eventHandler the handler to unregister
+     * @throws NullPointerException if the event type or handler is null
+     */
+    public <E extends Event> void removeEventHandler(EventType<E> eventType, EventHandler<E> eventHandler) {
+        eventHandlerManager.removeEventHandler(eventType, eventHandler);
+    }
+
+    /** {@inheritDoc} */
+    @Override public EventDispatchChain buildEventDispatchChain(EventDispatchChain tail) {
+        return tail.prepend(eventHandlerManager);
+    }
+
+
+}
diff --git a/src/org/controlsfx/control/textfield/CustomPasswordField.java b/src/org/controlsfx/control/textfield/CustomPasswordField.java
new file mode 100644
index 0000000000000000000000000000000000000000..0265dd6f77f8a6dcfe319981ce0131fbfe8476cc
--- /dev/null
+++ b/src/org/controlsfx/control/textfield/CustomPasswordField.java
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.textfield;
+
+import impl.org.controlsfx.skin.CustomTextFieldSkin;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.scene.Node;
+import javafx.scene.control.PasswordField;
+import javafx.scene.control.Skin;
+
+/**
+ * A base class for people wanting to customize a {@link PasswordField} to contain nodes
+ * inside the input field area itself, without being on top of the users typed-in text.
+ * 
+ * <p>Whilst not exactly the same, refer to the {@link CustomTextField} javadoc
+ * for a screenshot and more detail. The obvious difference is that of course
+ * the CustomPasswordField masks the input from users, but in all other ways
+ * is equivalent to {@link CustomTextField}.
+ * 
+ * @see CustomPasswordField
+ * @see TextFields
+ */
+public class CustomPasswordField extends PasswordField {
+
+    /**************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+
+    
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Instantiates a default CustomPasswordField.
+     */
+    public CustomPasswordField() {
+        getStyleClass().addAll("custom-text-field", "custom-password-field"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    
+    
+    /**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+    
+    // --- left
+    private ObjectProperty<Node> left = new SimpleObjectProperty<>(this, "left"); //$NON-NLS-1$
+    
+    /**
+     * Property representing the {@link Node} that is placed on the left of
+     * the password field.
+     * @return An ObjectProperty.
+     */
+    public final ObjectProperty<Node> leftProperty() {
+        return left;
+    }
+    
+    /**
+     * 
+     * @return The {@link Node} that is placed on the left of
+     * the password field.
+     */
+    public final Node getLeft() {
+        return left.get();
+    }
+    
+    /**
+     * Sets the {@link Node} that is placed on the left of
+     * the password field.
+     * @param value 
+     */
+    public final void setLeft(Node value) {
+        left.set(value);
+    }
+    
+    
+    // --- right
+    private ObjectProperty<Node> right = new SimpleObjectProperty<>(this, "right"); //$NON-NLS-1$
+    
+    /**
+     * Property representing the {@link Node} that is placed on the right of
+     * the password field.
+     * @return An ObjectProperty.
+     */
+    public final ObjectProperty<Node> rightProperty() {
+        return right;
+    }
+    
+    /**
+     * 
+     * @return The {@link Node} that is placed on the right of
+     * the password field.
+     */
+    public final Node getRight() {
+        return right.get();
+    }
+    
+    /**
+     * Sets the {@link Node} that is placed on the right of
+     * the password field.
+     * @param value 
+     */
+    public final void setRight(Node value) {
+        right.set(value);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new CustomTextFieldSkin(this) {
+            @Override public ObjectProperty<Node> leftProperty() {
+                return CustomPasswordField.this.leftProperty();
+            }
+            
+            @Override public ObjectProperty<Node> rightProperty() {
+                return CustomPasswordField.this.rightProperty();
+            }
+        };
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override public String getUserAgentStylesheet() {
+        return CustomTextField.class.getResource("customtextfield.css").toExternalForm(); //$NON-NLS-1$
+    }
+    
+}
diff --git a/src/org/controlsfx/control/textfield/CustomTextField.java b/src/org/controlsfx/control/textfield/CustomTextField.java
new file mode 100644
index 0000000000000000000000000000000000000000..5eb1ce64b719e14a46de18b2e4527d177153e98c
--- /dev/null
+++ b/src/org/controlsfx/control/textfield/CustomTextField.java
@@ -0,0 +1,178 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.textfield;
+
+import impl.org.controlsfx.skin.CustomTextFieldSkin;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.scene.Node;
+import javafx.scene.control.Skin;
+import javafx.scene.control.TextField;
+
+/**
+ * A base class for people wanting to customize a {@link TextField} to contain nodes
+ * inside the text field itself, without being on top of the users typed-in text.
+ * 
+ * <h3>Screenshot</h3>
+ * <p>The following screenshot is taken from the HelloControlsFX sample application,
+ * and shows a normal TextField, with a {@link TextFields#createClearableTextField() clearable text field},
+ * followed by three CustomTextFields. Note what happens with long text input - 
+ * it is prevented from going beneath the left and right graphics. Of course, if 
+ * the keyboard caret moves to the right, the text will become visible, but this
+ * is because it will all scroll to the left (as is the case in a normal {@link TextField}).
+ * 
+ * <br>
+ * <center>
+ * <img src="customTextField.png" alt="Screenshot of CustomTextField">
+ * </center>
+ * 
+ * @see TextFields
+ * @see CustomPasswordField
+ */
+public class CustomTextField extends TextField {
+
+    /**************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+
+    
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Instantiates a default CustomTextField.
+     */
+    public CustomTextField() {
+        getStyleClass().add("custom-text-field"); //$NON-NLS-1$
+    }
+
+    
+    
+    /**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+    
+    // --- left
+    private ObjectProperty<Node> left = new SimpleObjectProperty<>(this, "left"); //$NON-NLS-1$
+    
+    /**
+     * 
+     * @return An ObjectProperty wrapping the {@link Node} that is placed 
+     * on the left ofthe text field.
+     */
+    public final ObjectProperty<Node> leftProperty() {
+        return left;
+    }
+    
+    /**
+     * 
+     * @return the {@link Node} that is placed on the left of
+     * the text field.
+     */
+    public final Node getLeft() {
+        return left.get();
+    }
+    
+    /**
+     * Sets the {@link Node} that is placed on the left of
+     * the text field.
+     * @param value 
+     */
+    public final void setLeft(Node value) {
+        left.set(value);
+    }
+    
+    
+    // --- right
+    private ObjectProperty<Node> right = new SimpleObjectProperty<>(this, "right"); //$NON-NLS-1$
+    
+    /**
+     * Property representing the {@link Node} that is placed on the right of
+     * the text field.
+     * @return An ObjectProperty.
+     */
+    public final ObjectProperty<Node> rightProperty() {
+        return right;
+    }
+    
+    /**
+     * 
+     * @return The {@link Node} that is placed on the right of
+     * the text field.
+     */
+    public final Node getRight() {
+        return right.get();
+    }
+    
+    /**
+     * Sets the {@link Node} that is placed on the right of
+     * the text field.
+     * @param value 
+     */
+    public final void setRight(Node value) {
+        right.set(value);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override protected Skin<?> createDefaultSkin() {
+        return new CustomTextFieldSkin(this) {
+            @Override public ObjectProperty<Node> leftProperty() {
+                return CustomTextField.this.leftProperty();
+            }
+            
+            @Override public ObjectProperty<Node> rightProperty() {
+                return CustomTextField.this.rightProperty();
+            }
+        };
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override public String getUserAgentStylesheet() {
+        return CustomTextField.class.getResource("customtextfield.css").toExternalForm(); //$NON-NLS-1$
+    }
+}
diff --git a/src/org/controlsfx/control/textfield/TextFields.java b/src/org/controlsfx/control/textfield/TextFields.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f8d7ab4dc2fbb597286b2833f81e34f1e60b839
--- /dev/null
+++ b/src/org/controlsfx/control/textfield/TextFields.java
@@ -0,0 +1,190 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.control.textfield;
+
+import impl.org.controlsfx.autocompletion.AutoCompletionTextFieldBinding;
+import impl.org.controlsfx.autocompletion.SuggestionProvider;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javafx.animation.FadeTransition;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.ObjectProperty;
+import javafx.scene.Cursor;
+import javafx.scene.Node;
+import javafx.scene.control.PasswordField;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.StackPane;
+import javafx.util.Callback;
+import javafx.util.Duration;
+import javafx.util.StringConverter;
+
+import org.controlsfx.control.textfield.AutoCompletionBinding.ISuggestionRequest;
+
+/**
+ * A class containing useful customizations for the JavaFX {@link TextField}.
+ * Note that this class is experimental and the API may change in future 
+ * releases. Note also that this class makes use of the {@link CustomTextField}
+ * class.
+ * 
+ * @see CustomTextField
+ */
+public class TextFields {
+    private static final Duration FADE_DURATION = Duration.millis(350);
+
+    private TextFields() {
+        // no-op
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Search fields                                                           *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Creates a TextField that shows a clear button inside the TextField (on
+     * the right hand side of it) when text is entered by the user.
+     */
+    public static TextField createClearableTextField() {
+        CustomTextField inputField = new CustomTextField();
+        setupClearButtonField(inputField, inputField.rightProperty());
+        return inputField;
+    }
+    
+    /**
+     * Creates a PasswordField that shows a clear button inside the PasswordField
+     * (on the right hand side of it) when text is entered by the user.
+     */
+    public static PasswordField createClearablePasswordField() {
+        CustomPasswordField inputField = new CustomPasswordField();
+        setupClearButtonField(inputField, inputField.rightProperty());
+        return inputField;
+    }
+    
+    private static void setupClearButtonField(TextField inputField, ObjectProperty<Node> rightProperty) {
+        inputField.getStyleClass().add("clearable-field"); //$NON-NLS-1$
+
+        Region clearButton = new Region();
+        clearButton.getStyleClass().addAll("graphic"); //$NON-NLS-1$
+        StackPane clearButtonPane = new StackPane(clearButton);
+        clearButtonPane.getStyleClass().addAll("clear-button"); //$NON-NLS-1$
+        clearButtonPane.setOpacity(0.0);
+        clearButtonPane.setCursor(Cursor.DEFAULT);
+        clearButtonPane.setOnMouseReleased(e -> inputField.clear());
+        clearButtonPane.managedProperty().bind(inputField.editableProperty());
+        clearButtonPane.visibleProperty().bind(inputField.editableProperty());
+
+        rightProperty.set(clearButtonPane);
+
+        final FadeTransition fader = new FadeTransition(FADE_DURATION, clearButtonPane);
+        fader.setCycleCount(1);
+
+        inputField.textProperty().addListener(new InvalidationListener() {
+            @Override public void invalidated(Observable arg0) {
+                String text = inputField.getText();
+                boolean isTextEmpty = text == null || text.isEmpty();
+                boolean isButtonVisible = fader.getNode().getOpacity() > 0;
+
+                if (isTextEmpty && isButtonVisible) {
+                    setButtonVisible(false);
+                } else if (!isTextEmpty && !isButtonVisible) {
+                    setButtonVisible(true);
+                }
+            }
+
+            private void setButtonVisible( boolean visible ) {
+                fader.setFromValue(visible? 0.0: 1.0);
+                fader.setToValue(visible? 1.0: 0.0);
+                fader.play();
+            }
+        });
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Auto-completion                                                         *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Create a new auto-completion binding between the given textField and the 
+     * given suggestion provider.
+     * 
+     * The {@link TextFields} API has some suggestion-provider builder methods 
+     * for simple use cases.
+     * 
+     * @param textField The {@link TextField} to which auto-completion shall be added
+     * @param suggestionProvider A suggestion-provider strategy to use
+     * @param converter The converter to be used to convert suggestions to strings
+     */
+	public static <T> AutoCompletionBinding<T> bindAutoCompletion(TextField textField,
+			Callback<ISuggestionRequest, Collection<T>> suggestionProvider,
+			StringConverter<T> converter) {
+		return new AutoCompletionTextFieldBinding<>(textField,
+				suggestionProvider, converter);
+	}    
+    
+    /**
+     * Create a new auto-completion binding between the given textField and the 
+     * given suggestion provider.
+     * 
+     * The {@link TextFields} API has some suggestion-provider builder methods 
+     * for simple use cases.
+     * 
+     * @param textField The {@link TextField} to which auto-completion shall be added
+     * @param suggestionProvider A suggestion-provider strategy to use
+     * @return The AutoCompletionBinding
+     */
+    public static <T> AutoCompletionBinding<T> bindAutoCompletion(TextField textField, 
+    		Callback<ISuggestionRequest, Collection<T>> suggestionProvider){
+        return new AutoCompletionTextFieldBinding<>(textField, suggestionProvider);
+    }
+
+    /**
+     * Create a new auto-completion binding between the given {@link TextField} 
+     * using the given auto-complete suggestions
+     * 
+     * @param textField The {@link TextField} to which auto-completion shall be added
+     * @param possibleSuggestions Possible auto-complete suggestions
+     * @return The AutoCompletionBinding
+     */
+	public static <T> AutoCompletionBinding<T> bindAutoCompletion(
+			TextField textField, @SuppressWarnings("unchecked") T... possibleSuggestions) {
+		return bindAutoCompletion(textField, Arrays.asList(possibleSuggestions));
+	}
+    
+	public static <T> AutoCompletionBinding<T> bindAutoCompletion(
+			TextField textField, Collection<T> possibleSuggestions) {
+		return new AutoCompletionTextFieldBinding<>(textField,
+				SuggestionProvider.create(possibleSuggestions));
+	}
+}
+
diff --git a/src/org/controlsfx/control/textfield/autocompletion.css b/src/org/controlsfx/control/textfield/autocompletion.css
new file mode 100644
index 0000000000000000000000000000000000000000..2e22806d3ad8af001b5224476664f7ddd4129c1a
--- /dev/null
+++ b/src/org/controlsfx/control/textfield/autocompletion.css
@@ -0,0 +1,31 @@
+/**
+ * Style based on Modena.css combo-box-popup style
+ */
+
+.auto-complete-popup > .list-view {
+    -fx-background-color:
+        linear-gradient(to bottom,
+            derive(-fx-color,-17%),
+            derive(-fx-color,-30%)
+        ),
+        -fx-control-inner-background;
+    -fx-background-insets: -1 -2 -1 -1, 0 -1 0 0;
+    -fx-effect: dropshadow( gaussian , rgba(0,0,0,0.2) , 12, 0.0 , 0 , 8 );
+}
+.auto-complete-popup > .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell {
+    -fx-padding: 4 0 4 5;
+    /* No alternate highlighting */
+    -fx-background: -fx-control-inner-background;
+}
+.auto-complete-popup > .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:selected {
+    -fx-background:  -fx-selection-bar-non-focused;
+    -fx-background-color:  -fx-background;
+}
+.auto-complete-popup  > .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:hover,
+.auto-complete-popup  > .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:selected:hover {
+    -fx-background: -fx-accent;
+    -fx-background-color: -fx-selection-bar;
+}
+.auto-complete-popup > .list-view > .placeholder > .label {
+    -fx-text-fill: derive(-fx-control-inner-background,-30%);
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/textfield/customtextfield.css b/src/org/controlsfx/control/textfield/customtextfield.css
new file mode 100644
index 0000000000000000000000000000000000000000..f8e08cfa60abb704442cff3ffb4f01085e944b5f
--- /dev/null
+++ b/src/org/controlsfx/control/textfield/customtextfield.css
@@ -0,0 +1,89 @@
+/**************************************************************************
+ * 
+ * CustomTextField
+ * 
+ **************************************************************************/
+
+.custom-text-field {
+    -fx-text-fill: -fx-text-inner-color;
+    -fx-highlight-fill: derive(-fx-control-inner-background,-20%);
+    -fx-highlight-text-fill: -fx-text-inner-color;
+    -fx-prompt-text-fill: derive(-fx-control-inner-background,-30%);
+    -fx-background-color: linear-gradient(to bottom, derive(-fx-text-box-border, -10%), -fx-text-box-border),
+        linear-gradient(from 0px 0px to 0px 5px, derive(-fx-control-inner-background, -9%), -fx-control-inner-background);
+    -fx-background-insets: 0, 1;
+    -fx-background-radius: 3, 2;
+    
+}
+
+/*
+.custom-text-field {
+    -fx-background-color: null;
+    -fx-background-insets: 0;
+}
+*/
+.custom-text-field:no-side-nodes {
+    -fx-padding: 0.333333em 0.583em 0.333333em 0.583em; 
+}
+
+.custom-text-field:left-node-visible {
+    -fx-padding: 0.333333em 0.583em 0.333333em 0; 
+}
+
+.custom-text-field:right-node-visible {
+    -fx-padding: 0.333333em 0 0.333333em 0.583em;
+}
+
+.custom-text-field:left-node-visible:right-node-visible {
+    -fx-padding: 0.333333em 0 0.333333em 0; 
+}
+
+.custom-text-field:left-node-visible .left-pane {
+    -fx-padding: 0 3 0 3;
+}
+
+.custom-text-field:right-node-visible .right-pane {
+    -fx-padding: 0 3 0 3; 
+}
+
+.custom-text-field:focused, 
+.custom-text-field:text-field-has-focus {
+    -fx-highlight-fill: -fx-accent;
+    -fx-highlight-text-fill: white;
+    -fx-background-color: 
+        -fx-focus-color,
+        -fx-control-inner-background,
+        -fx-faint-focus-color,
+        linear-gradient(from 0px 0px to 0px 5px, derive(-fx-control-inner-background, -9%), -fx-control-inner-background);
+    -fx-background-insets: -0.2, 1, -1.4, 3;
+    -fx-background-radius: 3, 2, 4, 0;
+    -fx-prompt-text-fill: transparent;
+}
+
+
+
+
+/**************************************************************************
+ * 
+ * Clearable Text / Password Field
+ * 
+ **************************************************************************/
+
+.clearable-field .clear-button {
+    -fx-padding: 0 3 0 0;
+}
+
+.clearable-field .clear-button > .graphic {
+    -fx-background-color: #949494;
+    -fx-scale-shape: false;
+    -fx-padding: 4.5 4.5 4.5 4.5; /* Graphic is 9x9 px */
+    -fx-shape: "M395.992,296.758l1.794-1.794l7.292,7.292l-1.795,1.794 L395.992,296.758z M403.256,294.992l1.794,1.794l-7.292,7.292l-1.794-1.795 L403.256,294.992z";
+}
+
+.clearable-field .clear-button:hover > .graphic {
+    -fx-background-color: #ee4444;
+}
+
+.clearable-field .clear-button:pressed > .graphic {
+    -fx-background-color: #ff1111;
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/control/textfield/package-info.java b/src/org/controlsfx/control/textfield/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7985d8c3c11c791a67f380bd1a00bfe84f587fd
--- /dev/null
+++ b/src/org/controlsfx/control/textfield/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * A package containing a number of useful classes related to text input.
+ */
+package org.controlsfx.control.textfield;
\ No newline at end of file
diff --git a/src/org/controlsfx/control/toggleswitch.css b/src/org/controlsfx/control/toggleswitch.css
new file mode 100644
index 0000000000000000000000000000000000000000..022de66131f1bd5bb6e14179d395e2477df126d6
--- /dev/null
+++ b/src/org/controlsfx/control/toggleswitch.css
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ *                                                                             *
+ * ToggleSwitch                                                                *
+ *                                                                             *
+ ******************************************************************************/
+.toggle-switch{
+    -thumb-move-animation-time: 200;
+}
+
+.toggle-switch .text {
+    -fx-font-size: 1em;
+    -fx-text-fill: -fx-text-base-color;
+}
+
+.toggle-switch .thumb {
+    -fx-background-color: linear-gradient(to bottom, derive(-fx-text-box-border, -20%), derive(-fx-text-box-border, -30%)),
+                            -fx-inner-border,
+                            -fx-body-color;
+    -fx-background-insets: 0, 1, 2;
+    -fx-background-radius: 1.0em; /* large value to make sure this remains circular */
+    -fx-padding: 0.75em;
+    -fx-alignment: CENTER;
+    -fx-content-display: LEFT;
+}
+
+.toggle-switch .thumb-area{
+    -fx-background-radius: 1em;
+    -fx-background-color: linear-gradient(to bottom, derive(-fx-text-box-border, -20%), derive(-fx-text-box-border, -30%)), #f5f5f5;
+    -fx-background-insets: 0, 1;
+}
+
+.toggle-switch:hover .thumb{
+    -fx-color: -fx-hover-base
+}
+
+.toggle-switch:selected .thumb-area{
+    -fx-background-color: linear-gradient(to bottom, derive(-fx-text-box-border, -20%), derive(-fx-text-box-border, -30%)),
+                            linear-gradient(to bottom, derive(#0b99c9, 30%), #0b99c9);
+    -fx-background-insets: 0, 1;
+
+}
+
+.toggle-switch .thumb-area
+{
+    -fx-padding: 0.75em 1.333333em 0.75em 1.333333em; /* 7 16 7 16 */
+}
+
+.toggle-switch:disabled
+{
+    -fx-opacity: 0.4;
+}
diff --git a/src/org/controlsfx/control/unselected-star.png b/src/org/controlsfx/control/unselected-star.png
new file mode 100644
index 0000000000000000000000000000000000000000..774c240118b6220c788fe44dd97c8af2fdd4430f
Binary files /dev/null and b/src/org/controlsfx/control/unselected-star.png differ
diff --git a/src/org/controlsfx/dialog/CommandLinksDialog.java b/src/org/controlsfx/dialog/CommandLinksDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d2e0e50007190b7a7b13f2f16c257880ef706df
--- /dev/null
+++ b/src/org/controlsfx/dialog/CommandLinksDialog.java
@@ -0,0 +1,298 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.dialog;
+
+import static impl.org.controlsfx.i18n.Localization.getString;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javafx.beans.binding.DoubleBinding;
+import javafx.collections.ListChangeListener;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.geometry.VPos;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonBar.ButtonData;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Dialog;
+import javafx.scene.control.DialogPane;
+import javafx.scene.control.Label;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.Priority;
+
+public class CommandLinksDialog extends Dialog<ButtonType> {
+    
+    public static class CommandLinksButtonType {
+        private final ButtonType buttonType;
+        private final String longText;
+        private final Node graphic;
+        private boolean isHidden = false;
+        
+        public CommandLinksButtonType(String text, boolean isDefault ) {
+            this(new ButtonType(text, buildButtonData(isDefault)), null);
+        }
+        
+        public CommandLinksButtonType(String text, String longText, boolean isDefault) {
+            this(new ButtonType(text, buildButtonData(isDefault)), longText, null);
+        }
+        
+        public CommandLinksButtonType(String text, String longText, Node graphic, boolean isDefault) {
+            this(new ButtonType(text, buildButtonData(isDefault)), longText, graphic);
+        }
+        
+        private CommandLinksButtonType(ButtonType buttonType) {
+            this(buttonType, null);
+        }
+        
+        private CommandLinksButtonType(ButtonType buttonType, String longText) {
+            this(buttonType, longText, null);
+        }
+        
+        private CommandLinksButtonType(ButtonType buttonType, String longText, Node graphic) {
+            this.buttonType = buttonType;
+            this.longText = longText;
+            this.graphic = graphic;
+            
+        }
+        
+        private static ButtonData buildButtonData( boolean isDeafault) {
+        	return isDeafault? ButtonData.OK_DONE :ButtonData.OTHER;
+        }
+        
+        private static CommandLinksButtonType buildHiddenCancelLink() {
+            CommandLinksButtonType link = new CommandLinksButtonType(new ButtonType("",ButtonData.CANCEL_CLOSE));
+            link.isHidden = true;
+            return link;
+        }
+        
+        public ButtonType getButtonType() {
+            return buttonType;
+        }
+        
+        public Node getGraphic() {
+            return graphic;
+        }
+        
+        public String getLongText() {
+            return longText;
+        }
+    }
+    
+    
+    private final static int gapSize = 10;
+    
+    private final Map<ButtonType, CommandLinksButtonType> typeMap;
+    
+    private Label contentTextLabel;
+    
+    private GridPane grid = new GridPane() {
+        @Override protected double computePrefWidth(double height) {
+            boolean isDefault = true;
+            double pw = 0;
+
+            for (ButtonType buttonType : getDialogPane().getButtonTypes()) {
+                Button button = (Button) getDialogPane().lookupButton(buttonType);
+                double buttonPrefWidth = button.getGraphic().prefWidth(-1);
+                
+                if (isDefault) {
+                    pw = buttonPrefWidth;
+                    isDefault = false;
+                } else {
+                    pw = Math.min(pw, buttonPrefWidth);
+                }
+            }
+            return pw + gapSize;
+        }
+
+        @Override protected double computePrefHeight(double width) {
+            double ph = getDialogPane().getHeader() == null ? 0 : 10;
+
+            for (ButtonType buttonType : getDialogPane().getButtonTypes()) {
+                Button button = (Button) getDialogPane().lookupButton(buttonType);
+                ph += button.prefHeight(width) + gapSize;
+            }
+            
+            // TODO remove magic number
+            return ph * 1.2;
+        }
+    };
+    
+    public CommandLinksDialog(CommandLinksButtonType... links) {
+        this(Arrays.asList(links));
+    }
+    
+    public CommandLinksDialog(List<CommandLinksButtonType> links) {
+        this.grid.setHgap(gapSize);
+        this.grid.setVgap(gapSize);
+        this.grid.getStyleClass().add("container"); //$NON-NLS-1$
+        
+        final DialogPane dialogPane = new DialogPane() {
+            @Override protected Node createButtonBar() {
+                return null;
+            }
+            
+            @Override protected Node createButton(ButtonType buttonType) {
+                return createCommandLinksButton(buttonType);
+            }
+        }; 
+        setDialogPane(dialogPane);
+        
+        setTitle(getString("Dialog.info.title")); //$NON-NLS-1$
+        dialogPane.getStyleClass().add("command-links-dialog"); //$NON-NLS-1$
+        dialogPane.getStylesheets().add(getClass().getResource("dialogs.css").toExternalForm()); //$NON-NLS-1$
+        dialogPane.getStylesheets().add(getClass().getResource("commandlink.css").toExternalForm()); //$NON-NLS-1$
+        
+        // create a map from ButtonType -> CommandLinkButtonType, and put the 
+        // ButtonType values into the dialog pane
+        
+        typeMap = new HashMap<>();
+        for (CommandLinksButtonType link : links) { 
+            addLinkToDialog(dialogPane,link);
+        }
+        addLinkToDialog(dialogPane,CommandLinksButtonType.buildHiddenCancelLink());
+        
+        updateGrid();
+        dialogPane.getButtonTypes().addListener((ListChangeListener<? super ButtonType>)c -> updateGrid());
+        
+        contentTextProperty().addListener(o -> updateContentText());
+    }
+    
+    private void addLinkToDialog(DialogPane dialogPane, CommandLinksButtonType link) {
+         typeMap.put(link.getButtonType(), link); 
+         dialogPane.getButtonTypes().add(link.getButtonType()); 
+    }
+    
+    private void updateContentText() {
+        String contentText = getDialogPane().getContentText();
+        grid.getChildren().remove(contentTextLabel);
+        if (contentText != null && ! contentText.isEmpty()) {
+            if (contentTextLabel != null) {
+                contentTextLabel.setText(contentText);
+            } else {
+                contentTextLabel = new Label(getDialogPane().getContentText());
+                contentTextLabel.getStyleClass().add("command-link-message"); //$NON-NLS-1$
+            }
+            grid.add(contentTextLabel, 0, 0);
+        }
+    }
+    
+    private void updateGrid() {
+        grid.getChildren().clear();
+        
+        // add the message to the top of the dialog
+        updateContentText();
+        
+        // then build all the buttons
+        int row = 1;
+        for (final ButtonType buttonType : getDialogPane().getButtonTypes()) {
+            if (buttonType == null) continue; 
+
+            final Button button = (Button)getDialogPane().lookupButton(buttonType);   
+
+            GridPane.setHgrow(button, Priority.ALWAYS);
+            GridPane.setVgrow(button, Priority.ALWAYS);
+            grid.add(button, 0, row++);
+        }
+
+//        // last button gets some extra padding (hacky)
+//        GridPane.setMargin(buttons.get(buttons.size() - 1), new Insets(0,0,10,0));
+
+        getDialogPane().setContent(grid);
+        getDialogPane().requestLayout();
+    }
+    
+    private Button createCommandLinksButton(ButtonType buttonType) {
+        // look up the CommandLinkButtonType for the given ButtonType
+        CommandLinksButtonType commandLink = typeMap.getOrDefault(buttonType, new CommandLinksButtonType(buttonType));
+        
+        
+        // put the content inside a button
+        final Button button = new Button();
+        button.getStyleClass().addAll("command-link-button"); //$NON-NLS-1$
+        button.setMaxHeight(Double.MAX_VALUE);
+        button.setMaxWidth(Double.MAX_VALUE);
+        button.setAlignment(Pos.CENTER_LEFT);
+        
+        final ButtonData buttonData = buttonType.getButtonData();
+        button.setDefaultButton(buttonData != null && buttonData.isDefaultButton());
+        button.setOnAction(ae -> setResult(buttonType));
+
+        final Label titleLabel = new Label(commandLink.getButtonType().getText() );
+        titleLabel.minWidthProperty().bind(new DoubleBinding() {
+            {
+                bind(titleLabel.prefWidthProperty());
+            }
+
+            @Override protected double computeValue() {
+                return titleLabel.getPrefWidth() + 400;
+            }
+        });
+        titleLabel.getStyleClass().addAll("line-1"); //$NON-NLS-1$
+        titleLabel.setWrapText(true);
+        titleLabel.setAlignment(Pos.TOP_LEFT);
+        GridPane.setVgrow(titleLabel, Priority.NEVER);
+
+        Label messageLabel = new Label(commandLink.getLongText() );
+        messageLabel.getStyleClass().addAll("line-2"); //$NON-NLS-1$
+        messageLabel.setWrapText(true);
+        messageLabel.setAlignment(Pos.TOP_LEFT);
+        messageLabel.setMaxHeight(Double.MAX_VALUE);
+        GridPane.setVgrow(messageLabel, Priority.SOMETIMES);
+
+        Node commandLinkImage = commandLink.getGraphic();
+        Node view = commandLinkImage == null ? 
+                new ImageView(CommandLinksDialog.class.getResource("arrow-green-right.png").toExternalForm()) :  //$NON-NLS-1$
+                commandLinkImage;
+        Pane graphicContainer = new Pane(view);
+        graphicContainer.getStyleClass().add("graphic-container"); //$NON-NLS-1$
+        GridPane.setValignment(graphicContainer, VPos.TOP);
+        GridPane.setMargin(graphicContainer, new Insets(0,10,0,0));
+
+        GridPane grid = new GridPane();
+        grid.minWidthProperty().bind(titleLabel.prefWidthProperty());
+        grid.setMaxHeight(Double.MAX_VALUE);
+        grid.setMaxWidth(Double.MAX_VALUE);
+        grid.getStyleClass().add("container"); //$NON-NLS-1$
+        grid.add(graphicContainer, 0, 0, 1, 2);
+        grid.add(titleLabel, 1, 0);
+        grid.add(messageLabel, 1, 1);
+
+        button.setGraphic(grid);
+        button.minWidthProperty().bind(titleLabel.prefWidthProperty());
+        
+        if (commandLink.isHidden) {
+            button.setVisible(false);
+            button.setPrefHeight(1);
+        }
+        return button;
+    }    
+}
diff --git a/src/org/controlsfx/dialog/DialogUtils.java b/src/org/controlsfx/dialog/DialogUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..21fdd4c764b10a7cc46e1cab490279106d251f20
--- /dev/null
+++ b/src/org/controlsfx/dialog/DialogUtils.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2014 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.dialog;
+
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Dialog;
+import javafx.scene.control.DialogPane;
+import javafx.scene.control.ButtonBar.ButtonData;
+
+// package scope
+class DialogUtils {
+
+    static void forcefullyHideDialog(javafx.scene.control.Dialog<?> dialog) {
+        // for the dialog to be able to hide, we need a cancel button,
+        // so lets put one in now and then immediately call hide, and then
+        // remove the button again (if necessary).
+        DialogPane dialogPane = dialog.getDialogPane();
+        if (containsCancelButton(dialog)) {
+            dialog.hide();
+            return;
+        }
+        
+        dialogPane.getButtonTypes().add(ButtonType.CANCEL); 
+        dialog.hide();
+        dialogPane.getButtonTypes().remove(ButtonType.CANCEL);
+    }
+    
+    static boolean containsCancelButton(Dialog<?> dialog) {
+        DialogPane dialogPane = dialog.getDialogPane();
+        for (ButtonType type : dialogPane.getButtonTypes()) {
+            if (type.getButtonData() == ButtonData.CANCEL_CLOSE) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/src/org/controlsfx/dialog/ExceptionDialog.java b/src/org/controlsfx/dialog/ExceptionDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..816b51303bb4365a7737cc3d2cad0cc2283230de
--- /dev/null
+++ b/src/org/controlsfx/dialog/ExceptionDialog.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2014 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.dialog;
+
+import static impl.org.controlsfx.i18n.Localization.getString;
+import static impl.org.controlsfx.i18n.Localization.localize;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Dialog;
+import javafx.scene.control.DialogPane;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextArea;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Priority;
+
+public class ExceptionDialog extends Dialog<ButtonType> {
+
+    public ExceptionDialog(final Throwable exception) {
+        final DialogPane dialogPane = getDialogPane();
+        
+        setTitle(getString("exception.dlg.title")); //$NON-NLS-1$
+        dialogPane.setHeaderText(getString("exception.dlg.header")); //$NON-NLS-1$
+        dialogPane.getStyleClass().add("exception-dialog"); //$NON-NLS-1$
+        dialogPane.getStylesheets().add(ProgressDialog.class.getResource("dialogs.css").toExternalForm()); //$NON-NLS-1$
+        dialogPane.getButtonTypes().addAll(ButtonType.OK);
+        
+        // --- content
+        String contentText = getContentText();
+        dialogPane.setContent(new Label(contentText != null && ! contentText.isEmpty() ? 
+                contentText : exception.getMessage()));
+        
+        // --- expandable content
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        exception.printStackTrace(pw);
+        String exceptionText = sw.toString();
+        
+        Label label = new Label( localize(getString("exception.dlg.label"))); //$NON-NLS-1$
+
+        TextArea textArea = new TextArea(exceptionText);
+        textArea.setEditable(false);
+        textArea.setWrapText(true);
+        
+        textArea.setMaxWidth(Double.MAX_VALUE);
+        textArea.setMaxHeight(Double.MAX_VALUE);
+        GridPane.setVgrow(textArea, Priority.ALWAYS);
+        GridPane.setHgrow(textArea, Priority.ALWAYS);
+        
+        GridPane root = new GridPane();
+        root.setMaxWidth(Double.MAX_VALUE);
+        root.add(label, 0, 0);
+        root.add(textArea, 0, 1);
+        
+        
+        dialogPane.setExpandableContent(root);
+    }
+}
diff --git a/src/org/controlsfx/dialog/FontSelectorDialog.java b/src/org/controlsfx/dialog/FontSelectorDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..f725ae1d2648b5ee6e0b22941b39b31b7993b33e
--- /dev/null
+++ b/src/org/controlsfx/dialog/FontSelectorDialog.java
@@ -0,0 +1,367 @@
+/**
+ * Copyright (c) 2014 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.dialog;
+
+import static impl.org.controlsfx.i18n.Localization.asKey;
+import static impl.org.controlsfx.i18n.Localization.localize;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
+
+import javafx.application.Platform;
+import javafx.beans.binding.DoubleBinding;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.transformation.FilteredList;
+import javafx.geometry.Pos;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Dialog;
+import javafx.scene.control.DialogPane;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.layout.ColumnConstraints;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.RowConstraints;
+import javafx.scene.layout.StackPane;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontPosture;
+import javafx.scene.text.FontWeight;
+import javafx.scene.text.Text;
+import javafx.util.Callback;
+
+public class FontSelectorDialog extends Dialog<Font> {
+    
+    private FontPanel fontPanel;
+
+    public FontSelectorDialog(Font defaultFont) {
+        fontPanel = new FontPanel();
+        fontPanel.setFont(defaultFont);
+        
+        setResultConverter(dialogButton -> dialogButton == ButtonType.OK ? fontPanel.getFont() : null);
+                
+        final DialogPane dialogPane = getDialogPane();
+        
+        setTitle(localize(asKey("font.dlg.title"))); //$NON-NLS-1$
+        dialogPane.setHeaderText(localize(asKey("font.dlg.header"))); //$NON-NLS-1$
+        dialogPane.getStyleClass().add("font-selector-dialog"); //$NON-NLS-1$
+        dialogPane.getStylesheets().add(FontSelectorDialog.class.getResource("dialogs.css").toExternalForm()); //$NON-NLS-1$
+        dialogPane.getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
+        dialogPane.setContent(fontPanel);
+    }
+    
+
+    
+    /**************************************************************************
+     * 
+     * Support classes
+     * 
+     **************************************************************************/
+
+    /**
+     * Font style as combination of font weight and font posture. 
+     * Weight does not have to be there (represented by null)
+     * Posture is required, null posture is converted to REGULAR
+     */
+    private static class FontStyle implements Comparable<FontStyle> {
+
+        private FontPosture posture; 
+        private FontWeight weight;
+
+        public FontStyle( FontWeight weight, FontPosture posture ) {
+            this.posture = posture == null? FontPosture.REGULAR: posture;
+            this.weight = weight;
+        }
+
+        public FontStyle() {
+            this( null, null);
+        }
+
+        public FontStyle(String styles) {
+            this();
+            String[] fontStyles = (styles == null? "": styles.trim().toUpperCase()).split(" "); //$NON-NLS-1$ //$NON-NLS-2$
+            for ( String style: fontStyles) {
+                FontWeight w = FontWeight.findByName(style);
+                if ( w != null ) {
+                    weight = w;
+                } else {
+                    FontPosture p = FontPosture.findByName(style);
+                    if ( p != null ) posture = p;
+                }
+            }
+        }
+
+        public FontStyle(Font font) {
+            this( font.getStyle());
+        }
+
+        public FontPosture getPosture() {
+            return posture;
+        }
+
+        public FontWeight getWeight() {
+            return weight;
+        }
+
+
+        @Override public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((posture == null) ? 0 : posture.hashCode());
+            result = prime * result + ((weight == null) ? 0 : weight.hashCode());
+            return result;
+        }
+
+        @Override public boolean equals(Object that) {
+            if (this == that)
+                return true;
+            if (that == null)
+                return false;
+            if (getClass() != that.getClass())
+                return false;
+            FontStyle other = (FontStyle) that;
+            if (posture != other.posture)
+                return false;
+            if (weight != other.weight)
+                return false;
+            return true;
+        }
+
+        private static String makePretty(Object o) {
+            String s = o == null? "": o.toString(); //$NON-NLS-1$
+            if ( !s.isEmpty()) { 
+                s = s.replace("_", " "); //$NON-NLS-1$ //$NON-NLS-2$
+                s = s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
+            }
+            return s;
+        }
+
+        @Override public String toString() {
+            return String.format("%s %s", makePretty(weight), makePretty(posture) ).trim(); //$NON-NLS-1$
+        }
+
+        private <T extends Enum<T>> int compareEnums( T e1, T e2) {
+            if ( e1 == e2 ) return 0;
+            if ( e1 == null ) return -1;
+            if ( e2 == null ) return 1;
+            return e1.compareTo(e2);
+        }
+
+        @Override public int compareTo(FontStyle fs) {
+            int result = compareEnums(weight,fs.weight);
+            return ( result != 0 )? result: compareEnums(posture,fs.posture);
+        }
+
+    }    
+
+
+    private static class FontPanel extends GridPane {
+        private static final double HGAP = 10;
+        private static final double VGAP = 5;
+
+        private static final Predicate<Object> MATCH_ALL = new Predicate<Object>() {
+            @Override public boolean test(Object t) {
+                return true;
+            }
+        };
+
+        private static final Double[] fontSizes = new Double[] {8d,9d,11d,12d,14d,16d,18d,20d,22d,24d,26d,28d,36d,48d,72d};
+
+        private static List<FontStyle> getFontStyles( String fontFamily ) {
+            Set<FontStyle> set = new HashSet<>();
+            for (String f : Font.getFontNames(fontFamily)) {
+                set.add(new FontStyle(f.replace(fontFamily, ""))); //$NON-NLS-1$
+            }
+
+            List<FontStyle> result =  new ArrayList<>(set);
+            Collections.sort(result);
+            return result;
+
+        }
+
+
+        private final FilteredList<String> filteredFontList = new FilteredList<>(FXCollections.observableArrayList(Font.getFamilies()), MATCH_ALL);
+        private final FilteredList<FontStyle> filteredStyleList = new FilteredList<>(FXCollections.<FontStyle>observableArrayList(), MATCH_ALL);
+        private final FilteredList<Double> filteredSizeList = new FilteredList<>(FXCollections.observableArrayList(fontSizes), MATCH_ALL);
+
+        private final ListView<String> fontListView = new ListView<>(filteredFontList);
+        private final ListView<FontStyle> styleListView = new ListView<>(filteredStyleList);
+        private final ListView<Double> sizeListView = new ListView<>(filteredSizeList);
+        private final Text sample = new Text(localize(asKey("font.dlg.sample.text"))); //$NON-NLS-1$
+
+        public FontPanel() {
+            setHgap(HGAP);
+            setVgap(VGAP);
+            setPrefSize(500, 300);
+            setMinSize(500, 300);
+
+            ColumnConstraints c0 = new ColumnConstraints();
+            c0.setPercentWidth(60);
+            ColumnConstraints c1 = new ColumnConstraints();
+            c1.setPercentWidth(25);
+            ColumnConstraints c2 = new ColumnConstraints();
+            c2.setPercentWidth(15);
+            getColumnConstraints().addAll(c0, c1, c2);
+
+            RowConstraints r0 = new RowConstraints();
+            r0.setVgrow(Priority.NEVER);
+            RowConstraints r1 = new RowConstraints();
+            r1.setVgrow(Priority.NEVER);
+            RowConstraints r2 = new RowConstraints();
+            r2.setFillHeight(true);
+            r2.setVgrow(Priority.NEVER);
+            RowConstraints r3 = new RowConstraints();
+            r3.setPrefHeight(250);
+            r3.setVgrow(Priority.NEVER);
+            getRowConstraints().addAll(r0, r1, r2, r3);
+
+            // layout hello.dialog
+            add(new Label(localize(asKey("font.dlg.font.label"))), 0, 0); //$NON-NLS-1$
+            //            fontSearch.setMinHeight(Control.USE_PREF_SIZE);
+            //            add( fontSearch, 0, 1);
+            add(fontListView, 0, 1);
+            fontListView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
+                @Override public ListCell<String> call(ListView<String> listview) {
+                    return new ListCell<String>() {
+                        @Override protected void updateItem(String family, boolean empty) {
+                            super.updateItem(family, empty);
+
+                            if (! empty) {
+                                setFont(Font.font(family));
+                                setText(family);
+                            } else {
+                                setText(null);
+                            }
+                        }
+                    };
+                }
+            });
+
+
+            ChangeListener<Object> sampleRefreshListener = new ChangeListener<Object>() {
+                @Override public void changed(ObservableValue<? extends Object> arg0, Object arg1, Object arg2) {
+                    refreshSample();
+                }
+            };
+
+            fontListView.selectionModelProperty().get().selectedItemProperty().addListener( new ChangeListener<String>() {
+
+                @Override public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) {
+                    String fontFamily = listSelection(fontListView);
+                    styleListView.setItems(FXCollections.<FontStyle>observableArrayList(getFontStyles(fontFamily)));       
+                    refreshSample();
+                }});
+
+            add( new Label(localize(asKey("font.dlg.style.label"))), 1, 0); //$NON-NLS-1$
+            //            postureSearch.setMinHeight(Control.USE_PREF_SIZE);
+            //            add( postureSearch, 1, 1);
+            add(styleListView, 1, 1);
+            styleListView.selectionModelProperty().get().selectedItemProperty().addListener(sampleRefreshListener);
+
+            add( new Label(localize(asKey("font.dlg.size.label"))), 2, 0); //$NON-NLS-1$
+            //            sizeSearch.setMinHeight(Control.USE_PREF_SIZE);
+            //            add( sizeSearch, 2, 1);
+            add(sizeListView, 2, 1);
+            sizeListView.selectionModelProperty().get().selectedItemProperty().addListener(sampleRefreshListener);
+
+            final double height = 45;
+            final DoubleBinding sampleWidth = new DoubleBinding() {
+                {
+                    bind(fontListView.widthProperty(), styleListView.widthProperty(), sizeListView.widthProperty());
+                }
+
+                @Override protected double computeValue() {
+                    return fontListView.getWidth() + styleListView.getWidth() + sizeListView.getWidth() + 3 * HGAP;
+                }
+            };
+            StackPane sampleStack = new StackPane(sample);
+            sampleStack.setAlignment(Pos.CENTER_LEFT);
+            sampleStack.setMinHeight(height);
+            sampleStack.setPrefHeight(height);
+            sampleStack.setMaxHeight(height);
+            sampleStack.prefWidthProperty().bind(sampleWidth);
+            Rectangle clip = new Rectangle(0, height);
+            clip.widthProperty().bind(sampleWidth);
+            sampleStack.setClip(clip);
+            add(sampleStack, 0, 3, 1, 3);
+        }
+
+        public void setFont(final Font font) {
+            final Font _font = font == null ? Font.getDefault() : font;
+            if (_font != null) {
+                selectInList( fontListView,  _font.getFamily() );
+                selectInList( styleListView, new FontStyle(_font));
+                selectInList( sizeListView, _font.getSize() );
+            }
+        }
+
+        public Font getFont() {
+            try {
+                FontStyle style = listSelection(styleListView);
+                if ( style == null ) {
+                    return Font.font(
+                            listSelection(fontListView),
+                            listSelection(sizeListView));
+
+                } else { 
+                    return Font.font(
+                            listSelection(fontListView),
+                            style.getWeight(),
+                            style.getPosture(),
+                            listSelection(sizeListView));
+                }
+
+            } catch( Throwable ex ) {
+                return null;
+            }
+        }
+
+        private void refreshSample() {
+            sample.setFont(getFont());
+        }
+
+        private <T> void selectInList( final ListView<T> listView, final T selection ) {
+            Platform.runLater(new Runnable() {
+                @Override public void run() {
+                    listView.scrollTo(selection);
+                    listView.getSelectionModel().select(selection);
+                }
+            });
+        }
+
+        private <T> T listSelection(final ListView<T> listView) {
+            return listView.selectionModelProperty().get().getSelectedItem();
+        }
+    }  
+}
diff --git a/src/org/controlsfx/dialog/LoginDialog.java b/src/org/controlsfx/dialog/LoginDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..018f7480008aa3e461fc1e0f4f93a7fd50da8547
--- /dev/null
+++ b/src/org/controlsfx/dialog/LoginDialog.java
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.dialog;
+
+import static impl.org.controlsfx.i18n.Localization.getString;
+import javafx.application.Platform;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonBar.ButtonData;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Dialog;
+import javafx.scene.control.DialogPane;
+import javafx.scene.control.Label;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.VBox;
+import javafx.util.Callback;
+import javafx.util.Pair;
+
+import org.controlsfx.control.textfield.CustomPasswordField;
+import org.controlsfx.control.textfield.CustomTextField;
+import org.controlsfx.control.textfield.TextFields;
+import org.controlsfx.validation.ValidationSupport;
+import org.controlsfx.validation.Validator;
+
+public class LoginDialog extends Dialog<Pair<String,String>> {
+    
+    private final ButtonType loginButtonType;
+    private final CustomTextField txUserName;
+    private final CustomPasswordField txPassword;
+
+    @SuppressWarnings("deprecation")
+    public LoginDialog(final Pair<String,String> initialUserInfo, final Callback<Pair<String,String>, Void> authenticator) {
+        final DialogPane dialogPane = getDialogPane();
+        
+        setTitle(getString("login.dlg.title")); //$NON-NLS-1$
+        dialogPane.setHeaderText(getString("login.dlg.header")); //$NON-NLS-1$
+        dialogPane.getStyleClass().add("login-dialog"); //$NON-NLS-1$
+        dialogPane.getStylesheets().add(LoginDialog.class.getResource("dialogs.css").toExternalForm()); //$NON-NLS-1$
+        dialogPane.getButtonTypes().addAll(ButtonType.CANCEL);
+        
+        
+        
+        
+        
+        txUserName = (CustomTextField) TextFields.createClearableTextField();
+        
+        txUserName.setLeft(new ImageView(LoginDialog.class.getResource("/org/controlsfx/dialog/user.png").toExternalForm())); //$NON-NLS-1$
+        
+        txPassword = (CustomPasswordField) TextFields.createClearablePasswordField();
+        txPassword.setLeft(new ImageView(LoginDialog.class.getResource("/org/controlsfx/dialog/lock.png").toExternalForm())); //$NON-NLS-1$
+        
+        Label lbMessage= new Label("");  //$NON-NLS-1$
+        lbMessage.getStyleClass().addAll("message-banner"); //$NON-NLS-1$
+        lbMessage.setVisible(false);
+        lbMessage.setManaged(false);
+        
+        final VBox content = new VBox(10);
+        content.getChildren().add(lbMessage);
+        content.getChildren().add(txUserName);
+        content.getChildren().add(txPassword);
+        
+        dialogPane.setContent(content);
+        
+        loginButtonType = new javafx.scene.control.ButtonType(getString("login.dlg.login.button"), ButtonData.OK_DONE); //$NON-NLS-1$
+        dialogPane.getButtonTypes().addAll(loginButtonType);
+        Button loginButton = (Button) dialogPane.lookupButton(loginButtonType);
+        loginButton.setOnAction(actionEvent -> {
+            try {
+                if (authenticator != null ) {
+                    authenticator.call(new Pair<>(txUserName.getText(), txPassword.getText()));
+                }
+                lbMessage.setVisible(false);
+                lbMessage.setManaged(false);
+                hide();
+//                dlg.setResult(this);
+            } catch( Throwable ex ) {
+                lbMessage.setVisible(true);
+                lbMessage.setManaged(true);
+                lbMessage.setText(ex.getMessage());
+//                sizeToScene();
+//                dlg.shake();
+                ex.printStackTrace();
+            }
+        });
+        
+//        final Dialog dlg = buildDialog(Type.LOGIN);
+//        dlg.setContent(content);
+        
+//        dlg.setResizable(false);
+//        dlg.setIconifiable(false);
+//        if ( dlg.getGraphic() == null ) { 
+//            dlg.setGraphic( new ImageView( DialogResources.getImage("login.icon")));
+//        }
+//        dlg.getActions().setAll(actionLogin, ACTION_CANCEL);
+        String userNameCation = getString("login.dlg.user.caption"); //$NON-NLS-1$
+        String passwordCaption = getString("login.dlg.pswd.caption"); //$NON-NLS-1$
+        txUserName.setPromptText(userNameCation);
+        txUserName.setText(initialUserInfo == null ? "" : initialUserInfo.getKey()); //$NON-NLS-1$
+        txPassword.setPromptText(passwordCaption);
+        txPassword.setText(new String(initialUserInfo == null ? "" : initialUserInfo.getValue())); //$NON-NLS-1$
+
+        ValidationSupport validationSupport = new ValidationSupport();
+        Platform.runLater( () -> {
+            String requiredFormat = "'%s' is required"; //$NON-NLS-1$
+            validationSupport.registerValidator(txUserName, Validator.createEmptyValidator( String.format( requiredFormat, userNameCation )));
+            validationSupport.registerValidator(txPassword, Validator.createEmptyValidator(String.format( requiredFormat, passwordCaption )));
+//            loginButton.disabledProperty().bind(validationSupport.invalidProperty());
+            txUserName.requestFocus();
+        } );
+        
+        
+        setResultConverter(dialogButton -> dialogButton == loginButtonType ? 
+                new Pair<>(txUserName.getText(), txPassword.getText()) : null);
+
+//        return Optional.ofNullable( 
+//                dlg.show() == actionLogin? 
+//                        new Pair<String,String>(txUserName.getText(), txPassword.getText()): 
+//                        null);
+    }
+    
+
+    
+    /**************************************************************************
+     * 
+     * Support classes
+     * 
+     **************************************************************************/
+
+}
diff --git a/src/org/controlsfx/dialog/ProgressDialog.java b/src/org/controlsfx/dialog/ProgressDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..f57707e0dc9491242ae20d525e08878836a3e094
--- /dev/null
+++ b/src/org/controlsfx/dialog/ProgressDialog.java
@@ -0,0 +1,215 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.dialog;
+
+import static impl.org.controlsfx.i18n.Localization.getString;
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.concurrent.Worker;
+import javafx.concurrent.Worker.State;
+import javafx.geometry.Insets;
+import javafx.scene.control.Dialog;
+import javafx.scene.control.DialogPane;
+import javafx.scene.control.Label;
+import javafx.scene.control.ProgressBar;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.VBox;
+
+public class ProgressDialog extends Dialog<Void> {
+    
+
+    public ProgressDialog(final Worker<?> worker) {
+        if (worker != null
+                && (worker.getState() == State.CANCELLED
+                || worker.getState() == State.FAILED
+                || worker.getState() == State.SUCCEEDED)) {
+            return;
+        }
+        setResultConverter(dialogButton -> null);
+                
+        final DialogPane dialogPane = getDialogPane();
+        
+        setTitle(getString("progress.dlg.title")); //$NON-NLS-1$
+        dialogPane.setHeaderText(getString("progress.dlg.header")); //$NON-NLS-1$
+        dialogPane.getStyleClass().add("progress-dialog"); //$NON-NLS-1$
+        dialogPane.getStylesheets().add(ProgressDialog.class.getResource("dialogs.css").toExternalForm()); //$NON-NLS-1$
+        
+        final Label progressMessage = new Label();
+        progressMessage.textProperty().bind(worker.messageProperty());
+
+        final WorkerProgressPane content = new WorkerProgressPane(this);
+        content.setMaxWidth(Double.MAX_VALUE);
+        content.setWorker(worker);
+        
+        VBox vbox = new VBox(10, progressMessage, content);
+        vbox.setMaxWidth(Double.MAX_VALUE);
+        vbox.setPrefSize(300, 100);
+        /**
+         * The content Text cannot be set before the constructor and since we
+         * set a Content Node, the contentText will not be shown. If we want to
+         * let the user display a content text, we must recreate it.
+         */
+        Label contentText = new Label();
+        contentText.setWrapText(true);
+        vbox.getChildren().add(0, contentText);
+        contentText.textProperty().bind(dialogPane.contentTextProperty());
+        dialogPane.setContent(vbox);
+    }
+    
+
+    
+    /**************************************************************************
+     * 
+     * Support classes
+     * 
+     **************************************************************************/
+
+    /**
+     * The WorkerProgressPane takes a {@link Dialog} and a {@link Worker}
+     * and links them together so the dialog is shown or hidden depending
+     * on the state of the worker.  The WorkerProgressPane also includes
+     * a progress bar that is automatically bound to the progress property
+     * of the worker.  The way in which the WorkerProgressPane shows and
+     * hides its worker's dialog is consistent with the expected behavior
+     * for {@link #showWorkerProgress(Worker)}.
+     */
+    private static class WorkerProgressPane extends Region {
+        private Worker<?> worker;
+
+        private boolean dialogVisible = false;
+        private boolean cancelDialogShow = false;
+
+        private ChangeListener<Worker.State> stateListener = new ChangeListener<Worker.State>() {
+            @Override public void changed(ObservableValue<? extends State> observable, State old, State value) {
+                switch(value) {
+                    case CANCELLED:
+                    case FAILED:
+                    case SUCCEEDED:
+                        if(!dialogVisible) {
+                            cancelDialogShow = true;
+                            end();
+                        } else if(old == State.SCHEDULED || old == State.RUNNING) {
+                            end();
+                        }
+                        break;
+                    case SCHEDULED:
+                        begin();
+                        break;
+                    default: //no-op     
+                }
+            }
+        };
+
+        public final void setWorker(final Worker<?> newWorker) { 
+            if (newWorker != worker) {
+                if (worker != null) {
+                    worker.stateProperty().removeListener(stateListener);
+                    end();
+                }
+
+                worker = newWorker;
+
+                if (newWorker != null) {
+                    newWorker.stateProperty().addListener(stateListener);
+                    if (newWorker.getState() == Worker.State.RUNNING || newWorker.getState() == Worker.State.SCHEDULED) {
+                        // It is already running
+                        begin();
+                    }
+                }
+            }
+        }
+
+        // If the progress indicator changes, then we need to re-initialize
+        // If the worker changes, we need to re-initialize
+
+        private final ProgressDialog dialog;
+        private final ProgressBar progressBar;
+        
+        public WorkerProgressPane(ProgressDialog dialog) {
+            this.dialog = dialog;
+            
+            this.progressBar = new ProgressBar();
+            progressBar.setMaxWidth(Double.MAX_VALUE);
+            getChildren().add(progressBar);
+            
+            if (worker != null) {
+                progressBar.progressProperty().bind(worker.progressProperty());
+            }
+        }
+
+        private void begin() {
+            // Platform.runLater needs to be used to show the dialog because
+            // the call begin() is going to be occurring when the worker is
+            // notifying state listeners about changes.  If Platform.runLater
+            // is not used, the call to show() will cause the worker to get
+            // blocked during notification and it will prevent the worker
+            // from performing any additional notification for state changes.
+            //
+            // Sine the dialog is hidden as a result of a change in worker
+            // state, calling show() without wrapping it in Platform.runLater
+            // will cause the progress dialog to run forever when the dialog
+            // is attached to workers that start out with a state of READY.
+            //
+            // This also creates a case where the worker's state can change
+            // to finished before the dialog is shown, resulting in an
+            // an attempt to hide the dialog before it is shown.  It's
+            // necessary to track whether or not this occurs, so flags are
+            // set to indicate if the dialog is visible and if if the call
+            // to show should still be allowed.
+            cancelDialogShow = false;
+
+            Platform.runLater(() -> {
+                if(!cancelDialogShow) {
+                    progressBar.progressProperty().bind(worker.progressProperty());
+                    dialogVisible = true;
+                    dialog.show();
+                }
+            });
+        }
+
+        private void end() {
+            progressBar.progressProperty().unbind();
+            dialogVisible = false;
+            DialogUtils.forcefullyHideDialog(dialog);
+        }
+
+        @Override protected void layoutChildren() {
+            if (progressBar != null) {
+                Insets insets = getInsets();
+                double w = getWidth() - insets.getLeft() - insets.getRight();
+                double h = getHeight() - insets.getTop() - insets.getBottom();
+
+                double prefH = progressBar.prefHeight(-1);
+                double x = insets.getLeft() + (w - w) / 2.0;
+                double y = insets.getTop() + (h - prefH) / 2.0;
+
+                progressBar.resizeRelocate(x, y, w, prefH);
+            }
+        }
+    }
+}
diff --git a/src/org/controlsfx/dialog/Wizard.java b/src/org/controlsfx/dialog/Wizard.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee6c0800eef48649855e983ac4f989207bd19747
--- /dev/null
+++ b/src/org/controlsfx/dialog/Wizard.java
@@ -0,0 +1,737 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.dialog;
+
+import static impl.org.controlsfx.i18n.Localization.asKey;
+import static impl.org.controlsfx.i18n.Localization.localize;
+import impl.org.controlsfx.ImplUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Optional;
+import java.util.Stack;
+import java.util.function.BooleanSupplier;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.collections.ObservableMap;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Rectangle2D;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonBar.ButtonData;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Dialog;
+import javafx.scene.control.DialogPane;
+import javafx.scene.layout.Pane;
+import javafx.stage.Screen;
+import javafx.stage.Window;
+
+import org.controlsfx.tools.ValueExtractor;
+import org.controlsfx.validation.ValidationSupport;
+
+/**
+ * <p>The API for creating multi-page Wizards, based on JavaFX {@link Dialog} API.<br> 
+ * Wizard can be setup in following few steps:</p>
+ * <ul>
+ *    <li>Design wizard pages by inheriting them from {@link WizardPane}</li>
+ *    <li>Define wizard flow by implementing {@link Wizard.Flow}</li>
+ *    <li>Create and instance of the Wizard and assign flow to it</li>
+ *    <li>Execute the wizard using showAndWait method</li>
+ *    <li>Values can be extracted from settings map by calling getSettings 
+ * </ul>    
+ * <p>For simple, linear wizards, the {@link LinearFlow} can be used. 
+ * It is a flow based on a collection of wizard pages. Here is the example:</p>
+ * 
+ * <pre>{@code // Create pages. Here for simplicity we just create and instance of WizardPane.
+ * WizardPane page1 = new WizardPane(); 
+ * WizardPane page2 = new WizardPane(); 
+ * WizardPane page2 = new WizardPane(); 
+ * 
+ * // create wizard
+ * Wizard wizard = new Wizard();
+ * 
+ * // create and assign the flow
+ * wizard.setFlow(new LinearFlow(page1, page2, page3));
+ *     
+ * // show wizard and wait for response
+ * wizard.showAndWait().ifPresent(result -> {
+ *     if (result == ButtonType.FINISH) {
+ *         System.out.println("Wizard finished, settings: " + wizard.getSettings());
+ *     }
+ * });}</pre>
+ * 
+ * <p>For more complex wizard flows we suggest to create a custom ones, describing page traversal logic. 
+ * Here is a simplified example: </p>
+ * 
+ * <pre>{@code Wizard.Flow branchingFlow = new Wizard.Flow() {
+ *     public Optional<WizardPane> advance(WizardPane currentPage) {
+ *         return Optional.of(getNext(currentPage));
+ *     }
+ *
+ *     public boolean canAdvance(WizardPane currentPage) {
+ *         return currentPage != page3;
+ *     }
+ *          
+ *     private WizardPane getNext(WizardPane currentPage) {
+ *         if ( currentPage == null ) {
+ *             return page1;
+ *         } else if ( currentPage == page1) {
+ *             // skipNextPage() does not exist - this just represents that you
+ *             // can add a conditional statement here to change the page.
+ *             return page1.skipNextPage()? page3: page2;
+ *         } else {
+ *             return page3;
+ *         }
+ *     }
+ * };}</pre>
+ */
+public class Wizard {
+    
+    
+    /**************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+    
+    private Dialog<ButtonType> dialog;
+    
+    private final ObservableMap<String, Object> settings = FXCollections.observableHashMap();
+    
+    private final Stack<WizardPane> pageHistory = new Stack<>(); 
+    
+    private Optional<WizardPane> currentPage = Optional.empty();
+
+    private final BooleanProperty invalidProperty = new SimpleBooleanProperty(false);
+
+    // Read settings activated by default for backward compatibility
+    private final BooleanProperty readSettingsProperty = new SimpleBooleanProperty(true);
+    
+    private final ButtonType BUTTON_PREVIOUS = new ButtonType(localize(asKey("wizard.previous.button")), ButtonData.BACK_PREVIOUS); //$NON-NLS-1$
+    private final EventHandler<ActionEvent> BUTTON_PREVIOUS_ACTION_HANDLER = actionEvent -> {
+        actionEvent.consume();
+        currentPage = Optional.ofNullable( pageHistory.isEmpty()? null: pageHistory.pop() );
+        updatePage(dialog,false);
+    };
+    
+    private final ButtonType BUTTON_NEXT = new ButtonType(localize(asKey("wizard.next.button")), ButtonData.NEXT_FORWARD); //$NON-NLS-1$
+    private final EventHandler<ActionEvent> BUTTON_NEXT_ACTION_HANDLER = actionEvent -> {
+        actionEvent.consume();
+        currentPage.ifPresent(page->pageHistory.push(page));
+        currentPage = getFlow().advance(currentPage.orElse(null));
+        updatePage(dialog,true);
+    };
+    
+    private final StringProperty titleProperty = new SimpleStringProperty(); 
+    
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Creates an instance of the wizard without an owner.
+     */
+    public Wizard() {
+        this(null);
+    }
+    
+    /**
+     * Creates an instance of the wizard with the given owner.
+     * @param owner The object from which the owner window is deduced (typically
+     *      this is a Node, but it may also be a Scene or a Stage). 
+     */
+    public Wizard(Object owner) {
+        this(owner, ""); //$NON-NLS-1$
+    }
+    
+    /**
+     * Creates an instance of the wizard with the given owner and title.
+     * 
+     * @param owner The object from which the owner window is deduced (typically
+     *      this is a Node, but it may also be a Scene or a Stage). 
+     * @param title The wizard title.
+     */
+    public Wizard(Object owner, String title) {
+    	
+        invalidProperty.addListener( (o, ov, nv) -> validateActionState());
+        
+        dialog = new Dialog<>();
+        dialog.titleProperty().bind(this.titleProperty);
+        setTitle(title);
+        
+        Window window = null;
+        if ( owner instanceof Window) { 
+        	window = (Window)owner;
+        } else if ( owner instanceof Node ) {
+        	window = ((Node)owner).getScene().getWindow();
+        }
+        
+        dialog.initOwner(window);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+//    /**
+//     * Shows the wizard but does not wait for a user response (in other words,
+//     * this brings up a non-blocking dialog). Users of this API must either
+//     * poll the {@link #resultProperty() result property}, or else add a listener
+//     * to the result property to be informed of when it is set.
+//     */
+//    public final void show() {
+//        dialog.show();
+//    }
+    
+    /**
+     * Shows the wizard and waits for the user response (in other words, brings 
+     * up a blocking dialog, with the returned value the users input).
+     * 
+     * @return An {@link Optional} that contains the result.
+     */
+    public final Optional<ButtonType> showAndWait() {
+        return dialog.showAndWait();
+    }
+
+    /**
+     * @return {@link Dialog#resultProperty()} of the {@link Dialog} representing this {@link Wizard}.
+     */
+    public final ObjectProperty<ButtonType> resultProperty() {
+            return dialog.resultProperty();
+    }
+    
+    /**
+     * The settings map is the place where all data from pages is kept once the 
+     * user moves on from the page, assuming there is a {@link ValueExtractor} 
+     * that is capable of extracting a value out of the various fields on the page. 
+     */
+    public final ObservableMap<String, Object> getSettings() {
+        return settings;
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Properties
+     * 
+     **************************************************************************/
+    
+    // --- title
+    
+    /**
+     * Return the titleProperty of the wizard.
+     */
+    public final StringProperty titleProperty() {
+        return titleProperty;
+    }  
+    
+    /**
+     * Return the title of the wizard.
+     */
+    public final String getTitle() {
+    	return titleProperty.get();
+    }
+    
+    /**
+     * Change the Title of the wizard.
+     * @param title
+     */
+    public final void setTitle( String title ) {
+    	titleProperty.set(title);
+    }
+    
+    // --- flow
+    /**
+     * The {@link Flow} property represents the flow of pages in the wizard. 
+     */
+    private ObjectProperty<Flow> flow = new SimpleObjectProperty<Flow>(new LinearFlow()) {
+        @Override protected void invalidated() {
+            updatePage(dialog,false);
+        }
+        
+        @Override public void set(Flow flow) {
+        	super.set(flow);
+        	pageHistory.clear();
+        	if ( flow != null ) {
+        		currentPage = flow.advance(currentPage.orElse(null));
+        		updatePage(dialog,true);
+        	}
+        };
+    };
+    
+    public final ObjectProperty<Flow> flowProperty() {
+        return flow;
+    }
+    
+    /**
+     * Returns the currently set {@link Flow}, which represents the flow of 
+     * pages in the wizard. 
+     */
+    public final Flow getFlow() {
+        return flow.get();
+    }
+    
+    /**
+     * Sets the {@link Flow}, which represents the flow of pages in the wizard. 
+     */
+    public final void setFlow(Flow flow) {
+        this.flow.set(flow);
+    }
+    
+    
+    // --- Properties
+    private static final Object USER_DATA_KEY = new Object();
+    
+    // A map containing a set of properties for this Wizard
+    private ObservableMap<Object, Object> properties;
+
+    /**
+      * Returns an observable map of properties on this Wizard for use primarily
+      * by application developers - not to be confused with the 
+      * {@link #getSettings()} map that represents the values entered by the user
+      * into the wizard.
+      *
+      * @return an observable map of properties on this Wizard for use primarily
+      * by application developers
+     */
+     public final ObservableMap<Object, Object> getProperties() {
+        if (properties == null) {
+            properties = FXCollections.observableMap(new HashMap<>());
+        }
+        return properties;
+    }
+    
+    /**
+     * Tests if this Wizard has properties.
+     * @return true if this Wizard has properties.
+     */
+     public boolean hasProperties() {
+        return properties != null && !properties.isEmpty();
+    }
+
+     
+    // --- UserData
+    /**
+     * Convenience method for setting a single Object property that can be
+     * retrieved at a later date. This is functionally equivalent to calling
+     * the getProperties().put(Object key, Object value) method. This can later
+     * be retrieved by calling {@link #getUserData()}.
+     *
+     * @param value The value to be stored - this can later be retrieved by calling
+     *          {@link #getUserData()}.
+     */
+    public void setUserData(Object value) {
+        getProperties().put(USER_DATA_KEY, value);
+    }
+
+    /**
+     * Returns a previously set Object property, or null if no such property
+     * has been set using the {@link #setUserData(Object)} method.
+     *
+     * @return The Object that was previously set, or null if no property
+     *          has been set or if null was set.
+     */
+    public Object getUserData() {
+        return getProperties().get(USER_DATA_KEY);
+    }
+    
+    /**
+     * Sets the value of the property {@code invalid}.
+     * 
+     * @param invalid The new validation state
+     *  {@link #invalidProperty() }
+     */
+    public final void setInvalid(boolean invalid) {
+        invalidProperty.set(invalid);
+    }
+    
+    /**
+     * Gets the value of the property {@code invalid}.
+     * 
+     * @return The validation state
+     * @see #invalidProperty() 
+     */
+    public final boolean isInvalid() {
+        return invalidProperty.get();
+    }
+    
+    /**
+     * Property for overriding the individual validation state of this {@link Wizard}.
+     * Setting {@code invalid} to true will disable the next/finish Button and the user
+     * will not be able to advance to the next page of the {@link Wizard}. Setting
+     * {@code invalid} to false will enable the next/finish Button. <br>
+     * <br>
+     * For example you can use the {@link ValidationSupport#invalidProperty()} of a
+     * page and bind it to the {@code invalid} property: <br>
+     * {@code
+     * wizard.invalidProperty().bind(page.validationSupport.invalidProperty());
+     * }
+     * 
+     * @return The validation state property
+     */
+    public final BooleanProperty invalidProperty() {
+        return invalidProperty;
+    }
+    
+    /**
+     * Sets the value of the property {@code readSettings}.
+     * 
+     * @param readSettings The new read-settings state
+     * @see #readSettingsProperty()
+     */
+    public final void setReadSettings(boolean readSettings) {
+        readSettingsProperty.set(readSettings);
+    }
+    
+    /**
+     * Gets the value of the property {@code readSettings}.
+     * 
+     * @return The read-settings state
+     * @see #readSettingsProperty()
+     */
+    public final boolean isReadSettings() {
+        return readSettingsProperty.get();
+    }
+    
+    /**
+    * Property for overriding the individual read-settings state of this {@link Wizard}.
+    * Setting {@code readSettings} to true will enable the value extraction for this
+    * {@link Wizard}. Setting {@code readSettings} to false will disable the value
+    * extraction for this {@link Wizard}.
+    *
+    * @return The readSettings state property
+    */
+    public final BooleanProperty readSettingsProperty() {
+        return readSettingsProperty;
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Private implementation
+     * 
+     **************************************************************************/
+    
+    private void updatePage(Dialog<ButtonType> dialog, boolean advancing) {
+        Flow flow = getFlow();
+        if (flow == null) {
+            return;
+        }
+        
+        Optional<WizardPane> prevPage = Optional.ofNullable( pageHistory.isEmpty()? null: pageHistory.peek()); 
+        prevPage.ifPresent( page -> {
+	        // if we are going forward in the wizard, we read in the settings 
+	        // from the page and store them in the settings map.
+	        // If we are going backwards, we do nothing
+                // This is only performed if readSettings is true.
+	        if (advancing && isReadSettings()) {
+	        	readSettings(page);
+	        }
+	        
+	        // give the previous wizard page a chance to update the pages list
+	        // based on the settings it has received
+	        page.onExitingPage(this);
+        });
+        
+        currentPage.ifPresent(currentPage -> {
+            // put in default actions
+            List<ButtonType> buttons = currentPage.getButtonTypes();
+            if (! buttons.contains(BUTTON_PREVIOUS)) {
+                buttons.add(BUTTON_PREVIOUS);
+                Button button = (Button)currentPage.lookupButton(BUTTON_PREVIOUS);
+                button.addEventFilter(ActionEvent.ACTION, BUTTON_PREVIOUS_ACTION_HANDLER);
+            }
+            if (! buttons.contains(BUTTON_NEXT)) {
+                buttons.add(BUTTON_NEXT);
+                Button button = (Button)currentPage.lookupButton(BUTTON_NEXT);
+                button.addEventFilter(ActionEvent.ACTION, BUTTON_NEXT_ACTION_HANDLER);
+            }
+            if (! buttons.contains(ButtonType.FINISH)) buttons.add(ButtonType.FINISH);
+            if (! buttons.contains(ButtonType.CANCEL)) buttons.add(ButtonType.CANCEL);
+                
+            // then give user a chance to modify the default actions
+            currentPage.onEnteringPage(this);
+            
+            // Remove from DecorationPane which has been created by e.g. validation
+            if (currentPage.getParent() != null && currentPage.getParent() instanceof Pane) {
+                Pane parentOfCurrentPage = (Pane) currentPage.getParent();
+                parentOfCurrentPage.getChildren().remove(currentPage);
+            }
+            
+            // Get current position and size
+            double previousX = dialog.getX();
+            double previousY = dialog.getY();
+            double previousWidth = dialog.getWidth();
+            double previousHeight = dialog.getHeight();
+            // and then switch to the new pane
+            dialog.setDialogPane(currentPage);
+            // Resize Wizard to new page
+            Window wizard = currentPage.getScene().getWindow();
+            wizard.sizeToScene();
+            // Center resized Wizard to previous position
+            
+            
+            if (!Double.isNaN(previousX) && !Double.isNaN(previousY)) {
+                double newWidth = dialog.getWidth();
+                double newHeight = dialog.getHeight();
+                int newX = (int) (previousX + (previousWidth / 2.0) - (newWidth / 2.0));
+                int newY = (int) (previousY + (previousHeight / 2.0) - (newHeight / 2.0));
+
+                ObservableList<Screen> screens = Screen.getScreensForRectangle(previousX, previousY, 1, 1);
+                Screen screen = screens.isEmpty() ? Screen.getPrimary() : screens.get(0);
+                Rectangle2D scrBounds = screen.getBounds();
+                int minX = (int)Math.round(scrBounds.getMinX());
+                int maxX = (int)Math.round(scrBounds.getMaxX());
+                int minY = (int)Math.round(scrBounds.getMinY());
+                int maxY = (int)Math.round(scrBounds.getMaxY());
+                if(newX + newWidth > maxX) {
+                    newX = maxX - (int)Math.round(newWidth);
+                }
+                if(newY + newHeight > maxY) {
+                    newY = maxY - (int)Math.round(newHeight);
+                }                
+                if(newX < minX) {
+                    newX = minX;
+                }
+                if(newY < minY) {
+                    newY = minY;
+                }
+
+                dialog.setX(newX);
+                dialog.setY(newY);
+            }
+        });
+        
+        validateActionState();
+    }
+    
+    private void validateActionState() {
+        final List<ButtonType> currentPaneButtons = dialog.getDialogPane().getButtonTypes();
+        
+        if (getFlow().canAdvance(currentPage.orElse(null))) {
+            currentPaneButtons.remove(ButtonType.FINISH);
+        } else {
+            currentPaneButtons.remove(BUTTON_NEXT);
+        }
+
+        validateButton( BUTTON_PREVIOUS, () -> pageHistory.isEmpty());
+        validateButton( BUTTON_NEXT,     () -> invalidProperty.get());
+        validateButton( ButtonType.FINISH,     () -> invalidProperty.get());
+
+    }
+    
+    // Functional design allows to delay condition evaluation until it is actually needed 
+    private void validateButton( ButtonType buttonType, BooleanSupplier condition) {
+    	Button btn = (Button)dialog.getDialogPane().lookupButton(buttonType);
+        if ( btn != null ) {
+            Node focusOwner = (btn.getScene() != null) ? btn.getScene().getFocusOwner() : null;
+            btn.setDisable(condition.getAsBoolean());
+            if(focusOwner != null) {
+                focusOwner.requestFocus();
+            }
+        }
+    }
+    
+    private int settingCounter;
+    private void readSettings(WizardPane page) {
+        // for now we cannot know the structure of the page, so we just drill down
+        // through the entire scenegraph (from page.content down) until we get
+        // to the leaf nodes. We stop only if we find a node that is a
+        // ValueContainer (either by implementing the interface), or being 
+        // listed in the internal valueContainers map.
+        
+        settingCounter = 0;
+        checkNode(page.getContent());
+    }
+    
+    private boolean checkNode(Node n) {
+        boolean success = readSetting(n);
+        
+        if (success) {
+            // we've added the setting to the settings map and we should stop drilling deeper
+            return true;
+        } else {
+            /**
+             * go into children of this node (if possible) and see if we can get
+             * a value from them (recursively) We use reflection to fix
+             * https://bitbucket.org/controlsfx/controlsfx/issue/412 .
+             */
+            List<Node> children = ImplUtils.getChildren(n, true);
+            
+            // we're doing a depth-first search, where we stop drilling down
+            // once we hit a successful read
+            boolean childSuccess = false;
+            for (Node child : children) {
+                childSuccess |= checkNode(child);
+            }
+            return childSuccess;
+        }
+    }
+    
+    private boolean readSetting(Node n) {
+        if (n == null) {
+            return false;
+        }
+        
+        Object setting = ValueExtractor.getValue(n);
+        
+        if (setting != null) {
+            // save it into the settings map.
+            // if the node has an id set, we will use that as the setting name
+            String settingName = n.getId();
+            
+            // but if the id is not set, we will use a generic naming scheme
+            if (settingName == null || settingName.isEmpty()) {
+                settingName = "page_" /*+ previousPageIndex*/ + ".setting_" + settingCounter;  //$NON-NLS-1$ //$NON-NLS-2$
+            }
+            
+            getSettings().put(settingName, setting);
+            
+            settingCounter++;
+        }
+        
+        return setting != null;
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Support classes
+     * 
+     **************************************************************************/
+    
+    
+    /**
+     * Represents the page flow of the wizard. It defines only methods required 
+     * to move forward in the wizard logic, as backward movement is automatically 
+     * handled by wizard itself, using internal page history.   
+     */
+    public interface Flow {
+    	
+    	/** 
+    	 * Advances the wizard to the next page if possible.
+    	 * 
+    	 * @param currentPage The current wizard page
+    	 * @return {@link Optional} value containing the next wizard page. 
+    	 */
+    	Optional<WizardPane> advance(WizardPane currentPage);
+    	
+    	/**
+    	 * Check if advancing to the next page is possible
+    	 * 
+    	 * @param currentPage The current wizard page
+    	 * @return true if it is possible to advance to the next page, false otherwise.
+    	 */
+    	boolean canAdvance(WizardPane currentPage);
+    }
+    
+    
+    /**
+     * LinearFlow is an implementation of the {@link Wizard.Flow} interface,
+     * designed to support the most common type of wizard flow - namely, a linear 
+     * wizard page flow (i.e. through all pages in the order that they are specified).
+     * Therefore, this {@link Flow} implementation simply traverses a collections of
+     * {@link WizardPane WizardPanes}.
+     * 
+     * <p>For example of how to use this API, please refer to the {@link Wizard} 
+     * documentation</p>
+     * 
+     * @see Wizard
+     * @see WizardPane 
+     */
+    public static class LinearFlow implements Wizard.Flow {
+
+        private final List<WizardPane> pages;
+
+        /**
+         * Creates a new LinearFlow instance that will allow for stepping through
+         * the given collection of {@link WizardPane} instances.
+         */
+        public LinearFlow( Collection<WizardPane> pages ) {
+            this.pages = new ArrayList<>(pages);
+        }
+
+        /**
+         * Creates a new LinearFlow instance that will allow for stepping through
+         * the given varargs array of {@link WizardPane} instances.
+         */
+        public LinearFlow( WizardPane... pages ) {
+            this( Arrays.asList(pages));
+        }
+
+        /** {@inheritDoc} */
+        @Override public Optional<WizardPane> advance(WizardPane currentPage) {
+            int pageIndex = pages.indexOf(currentPage);
+            return Optional.ofNullable( pages.get(++pageIndex) );
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean canAdvance(WizardPane currentPage) {
+            int pageIndex = pages.indexOf(currentPage);
+            return pages.size()-1 > pageIndex; 
+        }
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Methods for the sake of unit tests
+     * 
+     **************************************************************************/
+    
+    /**
+     * @return The {@link Dialog} representing this {@link Wizard}. <br>
+     *         This is actually for {@link Dialog} reading-purposes, e.g.
+     *         unit testing the {@link DialogPane} content.
+     */
+    Dialog<ButtonType> getDialog() {
+        return dialog;
+    }
+    
+}
diff --git a/src/org/controlsfx/dialog/WizardPane.java b/src/org/controlsfx/dialog/WizardPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..4379b337572c86ee5d63b6c7af0ae2205433c741
--- /dev/null
+++ b/src/org/controlsfx/dialog/WizardPane.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2014, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.dialog;
+
+import javafx.scene.control.DialogPane;
+
+/**
+ * WizardPane is the base class for all wizard pages. The API is essentially
+ * the {@link DialogPane}, with the addition of convenience methods related
+ * to {@link #onEnteringPage(Wizard) entering} and 
+ * {@link #onExitingPage(Wizard) exiting} the page.
+ */
+public class WizardPane extends DialogPane {
+
+    /**
+     * Creates an instance of wizard pane.
+     */
+    public WizardPane() {
+        getStylesheets().add(Wizard.class.getResource("wizard.css").toExternalForm());
+        getStyleClass().add("wizard-pane");
+    }
+
+    /**
+     * Called on entering a page. This is a good place to read values from wizard settings 
+     * and assign them to controls on the page
+     * @param wizard which page will be used on
+     */
+    public void onEnteringPage(Wizard wizard) {
+        // no-op
+    }
+    
+    /**
+     * Called on existing the page. 
+     * This is a good place to read values from page controls and store them in wizard settings
+     * @param wizard which page was used on
+     */
+    public void onExitingPage(Wizard wizard) {
+        // no-op
+    }
+}
diff --git a/src/org/controlsfx/dialog/arrow-green-right.png b/src/org/controlsfx/dialog/arrow-green-right.png
new file mode 100644
index 0000000000000000000000000000000000000000..63b675cd66fc900476e853e2fa5b8ff0462dcfca
Binary files /dev/null and b/src/org/controlsfx/dialog/arrow-green-right.png differ
diff --git a/src/org/controlsfx/dialog/commandlink.css b/src/org/controlsfx/dialog/commandlink.css
new file mode 100644
index 0000000000000000000000000000000000000000..af693b3c16f0dea6affbd1ebd8046da216704e5e
--- /dev/null
+++ b/src/org/controlsfx/dialog/commandlink.css
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ *                                                                             *
+ * Command Link                                                                *
+ *                                                                             *
+ ******************************************************************************/
+ /* For the text displayed above command-link buttons (but below the header) */
+.command-links-dialog.dialog-pane > .container > .command-link-message {
+    -fx-font-size: 1.25em; 
+}
+
+.command-links-dialog.dialog-pane > .container > .command-link-button {
+    -fx-padding: 10 10 10 10;
+    -fx-background-color: transparent;
+    -fx-background-insets: 0;
+    -fx-border-color: transparent;
+    -fx-border-width: 1;
+    -fx-border-radius: 3px;
+}
+
+.command-links-dialog.dialog-pane > .container > .command-link-button:hover {
+    -fx-border-color: -fx-box-border;
+    -fx-background-color: linear-gradient(to bottom, 
+        white, 
+        derive(-fx-box-border, 60%)
+    );
+}
+
+.command-links-dialog.dialog-pane > .container > .command-link-button:armed  {
+    -fx-background-color: linear-gradient(to bottom, 
+        white, 
+        derive(-fx-box-border, 40%)
+    );
+}
+
+.command-links-dialog.dialog-pane > .container > .command-link-button:default {
+    -fx-border-color: -fx-default-button;
+    -fx-background-color: linear-gradient(to bottom, 
+        white, 
+        derive(-fx-default-button, 80%)
+    );
+}
+
+.command-links-dialog.dialog-pane > .container > .command-link-button:default:hover {
+    -fx-border-color: -fx-default-button;
+    -fx-background-color: linear-gradient(to bottom, 
+        white, 
+        derive(-fx-default-button, 60%)
+    );
+}
+
+.command-links-dialog.dialog-pane > .container > .command-link-button:default:armed {
+    -fx-border-color: -fx-default-button;
+    -fx-background-color: linear-gradient(to bottom, 
+        white, 
+        derive(-fx-default-button, 40%)
+    );
+}
+
+.command-links-dialog.dialog-pane > .container > .command-link-button > .container > .line-1 {
+    -fx-font-size: 1.25em;
+    -fx-padding: -5 0 0 5;
+}
+
+.command-links-dialog.dialog-pane > .container > .command-link-button > .container > .line-2 {
+    -fx-font-size: 1em; 
+    -fx-padding: 0 0 0 5;
+}
+
+.command-links-dialog.dialog-pane > .container > .command-link-button > .container > .graphic-container {
+    -fx-padding: 10 10 0 0
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/dialog/dialog-confirm.png b/src/org/controlsfx/dialog/dialog-confirm.png
new file mode 100644
index 0000000000000000000000000000000000000000..adb569bece45425ad0742a5b894ae9766596efe9
Binary files /dev/null and b/src/org/controlsfx/dialog/dialog-confirm.png differ
diff --git a/src/org/controlsfx/dialog/dialog-error.png b/src/org/controlsfx/dialog/dialog-error.png
new file mode 100644
index 0000000000000000000000000000000000000000..769d7df7113350020cf67b19aad6629f68732a49
Binary files /dev/null and b/src/org/controlsfx/dialog/dialog-error.png differ
diff --git a/src/org/controlsfx/dialog/dialog-information.png b/src/org/controlsfx/dialog/dialog-information.png
new file mode 100644
index 0000000000000000000000000000000000000000..a220108dcf27810ecab177dd7969c7d3d05eae99
Binary files /dev/null and b/src/org/controlsfx/dialog/dialog-information.png differ
diff --git a/src/org/controlsfx/dialog/dialog-warning.png b/src/org/controlsfx/dialog/dialog-warning.png
new file mode 100644
index 0000000000000000000000000000000000000000..a374f4f7075eb7a97d5f69ddeeaca35be7ab8ad8
Binary files /dev/null and b/src/org/controlsfx/dialog/dialog-warning.png differ
diff --git a/src/org/controlsfx/dialog/dialogs.css b/src/org/controlsfx/dialog/dialogs.css
new file mode 100644
index 0000000000000000000000000000000000000000..2e93ee52f887e9936d177fcf397388d3fa149ea0
--- /dev/null
+++ b/src/org/controlsfx/dialog/dialogs.css
@@ -0,0 +1,13 @@
+.progress-dialog.dialog-pane {
+    -fx-graphic: url("dialog-information.png");
+}
+
+.font-selector-dialog.dialog-pane,
+.login-dialog.dialog-pane,
+.command-links-dialog.dialog-pane {
+    -fx-graphic: url("dialog-confirm.png");
+}
+
+.exception-dialog.dialog-pane {
+    -fx-graphic: url("dialog-error.png");
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/dialog/fewer-details.png b/src/org/controlsfx/dialog/fewer-details.png
new file mode 100644
index 0000000000000000000000000000000000000000..c45d4ac09eaa74b5ab9894fa5eef2f28e9c46376
Binary files /dev/null and b/src/org/controlsfx/dialog/fewer-details.png differ
diff --git a/src/org/controlsfx/dialog/license.txt b/src/org/controlsfx/dialog/license.txt
new file mode 100644
index 0000000000000000000000000000000000000000..07c519bcca52249f0ab3f6e272fe32188d1264e1
--- /dev/null
+++ b/src/org/controlsfx/dialog/license.txt
@@ -0,0 +1,7 @@
+Some of these images are from the Oxygen icon set.
+Oxygen icons are licensed under the 
+Creative Common Attribution-ShareAlike 3.0 License
+http://creativecommons.org/licenses/by-sa/3.0/
+
+For reference, these dialog icons were taken from
+http://websvn.kde.org/trunk/KDE/kdebase/runtime/pics/oxygen/?pathrev=706996
\ No newline at end of file
diff --git a/src/org/controlsfx/dialog/lock.png b/src/org/controlsfx/dialog/lock.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a7a9f651dd1c5e06ba6823b44e19deb60f1e6d4
Binary files /dev/null and b/src/org/controlsfx/dialog/lock.png differ
diff --git a/src/org/controlsfx/dialog/more-details.png b/src/org/controlsfx/dialog/more-details.png
new file mode 100644
index 0000000000000000000000000000000000000000..b8896c70d7c216137b48d95a346c37f59a7b9588
Binary files /dev/null and b/src/org/controlsfx/dialog/more-details.png differ
diff --git a/src/org/controlsfx/dialog/package-info.java b/src/org/controlsfx/dialog/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d1019c0bc5310d92f9501a7ddc5326ec829ccf7
--- /dev/null
+++ b/src/org/controlsfx/dialog/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * A package containing a powerful (yet easy to use) dialogs API for showing
+ * modal dialogs in JavaFX-based applications. 
+ */
+package org.controlsfx.dialog;
\ No newline at end of file
diff --git a/src/org/controlsfx/dialog/user.png b/src/org/controlsfx/dialog/user.png
new file mode 100644
index 0000000000000000000000000000000000000000..2bf6711963aceab5b3e5fc2fd255dfc519e3f32c
Binary files /dev/null and b/src/org/controlsfx/dialog/user.png differ
diff --git a/src/org/controlsfx/dialog/wizard-page.png b/src/org/controlsfx/dialog/wizard-page.png
new file mode 100644
index 0000000000000000000000000000000000000000..3c86ba7d4deffabfb3fda82e60f6318eefddace7
Binary files /dev/null and b/src/org/controlsfx/dialog/wizard-page.png differ
diff --git a/src/org/controlsfx/dialog/wizard.css b/src/org/controlsfx/dialog/wizard.css
new file mode 100644
index 0000000000000000000000000000000000000000..d8e268916e9e261565170519570b119e9bd405b0
--- /dev/null
+++ b/src/org/controlsfx/dialog/wizard.css
@@ -0,0 +1,3 @@
+.wizard-pane { 
+	 -fx-graphic: url("wizard-page.png"); 
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/glyphfont/FontAwesome.java b/src/org/controlsfx/glyphfont/FontAwesome.java
new file mode 100644
index 0000000000000000000000000000000000000000..1404e26441c43253b721752e5700cc4f57c983e5
--- /dev/null
+++ b/src/org/controlsfx/glyphfont/FontAwesome.java
@@ -0,0 +1,723 @@
+/**
+ * Copyright (c) 2013,2014 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.glyphfont;
+
+import java.io.InputStream;
+import java.util.Arrays;
+
+
+/**
+ * Defines a {@link GlyphFont} for the FontAwesome font set (see
+ * <a href="http://fortawesome.github.io/Font-Awesome/">the FontAwesome website</a>
+ * for more details). Note that at present the FontAwesome font is not distributed
+ * with ControlsFX, and is, by default, instead loaded from a CDN at runtime.
+ *
+ * <p>To use FontAwesome (or indeed any glyph font) in your JavaFX application,
+ * you firstly have to get access to the FontAwesome glyph font. You do this by
+ * doing the following:
+ *
+ * <pre>GlyphFont fontAwesome = GlyphFontRegistry.font("FontAwesome");</pre>
+ *
+ * <p>This code works because all glyph fonts are found dynamically at runtime
+ * by the {@link GlyphFontRegistry} class, so you can simply request the font
+ * set you want from there.
+ *
+ * <p>Once the font set has been loaded, you can simply start creating
+ * {@link Glyph} nodes and place them in your user interface. For example:
+ *
+ * <pre>new Button("", fontAwesome.create(&#92;uf013).fontColor(Color.RED));</pre>
+ *
+ * <p>Of course, this requires you to know that <code>&#92;uf013</code> maps to
+ * a 'gear' icon, which is not always intuitive (especially when you re-read the
+ * code in the future). A simpler approach is to do the following:
+ *
+ * <pre>new Button("", fontAwesome.create(FontAwesome.Glyph.GEAR));</pre>
+ * or
+ * <pre>new Button("", fontAwesome.create("GEAR"));</pre>
+ *
+ * It is possible to achieve the same result without creating a reference to icon font by simply using
+ * {@link org.controlsfx.glyphfont.Glyph} constructor
+ *
+ * <pre>new Button("", new Glyph("FontAwesome","GEAR");</pre>
+ *
+ * You can use the above Glyph class also in FXML and set the
+ * fontFamily and icon property there.
+ *
+ * @see GlyphFont
+ * @see GlyphFontRegistry
+ * @see Glyph
+ */
+public class FontAwesome extends GlyphFont {
+
+    private static String fontName = "FontAwesome"; //$NON-NLS-1$
+
+
+    /**
+     * The individual glyphs offered by the FontAwesome font.
+     */
+    public static enum Glyph implements INamedCharacter {
+
+        ADJUST('\uf042'),
+        ADN('\uf170'),
+        ALIGN_CENTER('\uf037'),
+        ALIGN_JUSTIFY('\uf039'),
+        ALIGN_LEFT('\uf036'),
+        ALIGN_RIGHT('\uf038'),
+        AMBULANCE('\uf0F9'),
+        ANCHOR('\uf13D'),
+        ANDROID('\uf17B'),
+        ANGELLIST('\uf209'),
+        ANGLE_DOUBLE_DOWN('\uf103'),
+        ANGLE_DOUBLE_LEFT('\uf100'),
+        ANGLE_DOUBLE_RIGHT('\uf101'),
+        ANGLE_DOUBLE_UP('\uf102'),
+        ANGLE_DOWN('\uf107'),
+        ANGLE_LEFT('\uf104'),
+        ANGLE_RIGHT('\uf105'),
+        ANGLE_UP('\uf106'),
+        APPLE('\uf179'),
+        ARCHIVE('\uf187'),
+        AREA_CHART('\uf1FE'),
+        ARROW_CIRCLE_DOWN('\uf0AB'),
+        ARROW_CIRCLE_LEFT('\uf0A8'),
+        ARROW_CIRCLE_O_DOWN('\uf01A'),
+        ARROW_CIRCLE_O_LEFT('\uf190'),
+        ARROW_CIRCLE_O_RIGHT('\uf18E'),
+        ARROW_CIRCLE_O_UP('\uf01B'),
+        ARROW_CIRCLE_RIGHT('\uf0A9'),
+        ARROW_CIRCLE_UP('\uf0AA'),
+        ARROW_DOWN('\uf063'),
+        ARROW_LEFT('\uf060'),
+        ARROW_RIGHT('\uf061'),
+        ARROW_UP('\uf062'),
+        ARROWS('\uf047'),
+        ARROWS_ALT('\uf0B2'),
+        ARROWS_H('\uf07E'),
+        ARROWS_V('\uf07D'),
+        ASTERISK('\uf069'),
+        AT('\uf1FA'),
+        AUTOMOBILE('\uf1B9'),
+        BACKWARD('\uf04A'),
+        BAN('\uf05E'),
+        BANK('\uf19C'),
+        BAR_CHART('\uf080'),
+        BAR_CHART_O('\uf080'),
+        BARCODE('\uf02A'),
+        BARS('\uf0C9'),
+        BED('\uf236'),
+        BEER('\uf0FC'),
+        BEHANCE('\uf1B4'),
+        BEHANCE_SQUARE('\uf1B5'),
+        BELL('\uf0F3'),
+        BELL_O('\uf0A2'),
+        BELL_SLASH('\uf1F6'),
+        BELL_SLASH_O('\uf1F7'),
+        BICYCLE('\uf206'),
+        BINOCULARS('\uf1E5'),
+        BIRTHDAY_CAKE('\uf1FD'),
+        BITBUCKET('\uf171'),
+        BITBUCKET_SQUARE('\uf172'),
+        BITCOIN('\uf15A'),
+        BOLD('\uf032'),
+        BOLT('\uf0E7'),
+        BOMB('\uf1E2'),
+        BOOK('\uf02D'),
+        BOOKMARK('\uf02E'),
+        BOOKMARK_ALT('\uf097'),
+        BRIEFCASE('\uf0B1'),
+        BTC('\uf15A'),
+        BUG('\uf188'),
+        BUILDING('\uf1AD'),
+        BUILDING_ALT('\uf0F7'),
+        BULLHORN('\uf0A1'),
+        BULLSEYE('\uf140'),
+        BUS('\uf207'),
+        BUYSELLADS('\uf20D'),
+        CAB('\uf1BA'),
+        CALCULATOR('\uf1EC'),
+        CALENDAR('\uf073'),
+        CALENDAR_ALT('\uf133'),
+        CAMERA('\uf030'),
+        CAMERA_RETRO('\uf083'),
+        CAR('\uf1B9'),
+        CARET_DOWN('\uf0D7'),
+        CARET_LEFT('\uf0D9'),
+        CARET_RIGHT('\uf0DA'),
+        CARET_SQUARE_ALT_DOWN('\uf150'),
+        CARET_SQUARE_ALT_LEFT('\uf191'),
+        CARET_SQUARE_ALT_RIGHT('\uf152'),
+        CARET_SQUARE_ALT_UP('\uf151'),
+        CARET_UP('\uf0D8'),
+        CART_ARROW_DOWN('\uf218'),
+        CART_PLUS('\uf217'),
+        CC('\uf20A'),
+        CC_AMEX('\uf1F3'),
+        CC_DISCOVER('\uf1F2'),
+        CC_MASTERCARD('\uf1F1'),
+        CC_PAYPAL('\uf1F4'),
+        CC_STRIPE('\uf1F5'),
+        CC_VISA('\uf1F0'),
+        CERTIFICATE('\uf0A3'),
+        CHAIN('\uf0C1'),
+        CHAIN_BROKEN('\uf127'),
+        CHECK('\uf00C'),
+        CHECK_CIRCLE('\uf058'),
+        CHECK_CIRCLE_ALT('\uf05D'),
+        CHECK_SQUARE('\uf14A'),
+        CHECK_SQUARE_ALT('\uf046'),
+        CHEVRON_CIRCLE_DOWN('\uf13A'),
+        CHEVRON_CIRCLE_LEFT('\uf137'),
+        CHEVRON_CIRCLE_RIGHT('\uf138'),
+        CHEVRON_CIRCLE_UP('\uf139'),
+        CHEVRON_DOWN('\uf078'),
+        CHEVRON_LEFT('\uf053'),
+        CHEVRON_RIGHT('\uf054'),
+        CHEVRON_UP('\uf077'),
+        CHILD('\uf1AE'),
+        CIRCLE('\uf111'),
+        CIRCLE_ALT('\uf10C'),
+        CIRCLE_ALT_NOTCH('\uf1CE'),
+        CIRCLE_THIN('\uf1DB'),
+        CLIPBOARD('\uf0EA'),
+        CLOCK_ALT('\uf017'),
+        CLOSE('\uf00D'),
+        CLOUD('\uf0C2'),
+        CLOUD_DOWNLOAD('\uf0ED'),
+        CLOUD_UPLOAD('\uf0EE'),
+        CNY('\uf157'),
+        CODE('\uf121'),
+        CODE_FORK('\uf126'),
+        CODEPEN('\uf1CB'),
+        COFFEE('\uf0F4'),
+        COG('\uf013'),
+        COGS('\uf085'),
+        COLUMNS('\uf0DB'),
+        COMMENT('\uf075'),
+        COMMENT_ALT('\uf0E5'),
+        COMMENTS('\uf086'),
+        COMMENTS_ALT('\uf0E6'),
+        COMPASS('\uf14E'),
+        COMPRESS('\uf066'),
+        CONNECTDEVELOP('\uf20E'),
+        COPY('\uf0C5'),
+        COPYRIGHT('\uf1F9'),
+        CREDIT_CARD('\uf09D'),
+        CROP('\uf125'),
+        CROSSHAIRS('\uf05B'),
+        CSS3('\uf13C'),
+        CUBE('\uf1B2'),
+        CUBES('\uf1B3'),
+        CUT('\uf0C4'),
+        CUTLERY('\uf0F5'),
+        DASHBOARD('\uf0E4'),
+        DASHCUBE('\uf210'),
+        DATABASE('\uf1C0'),
+        DEDENT('\uf03B'),
+        DELICIOUS('\uf1A5'),
+        DESKTOP('\uf108'),
+        DEVIANTART('\uf1BD'),
+        DIAMOND('\uf219'),
+        DIGG('\uf1A6'),
+        DOLLAR('\uf155'),
+        DOT_CIRCLE_ALT('\uf192'),
+        DOWNLOAD('\uf019'),
+        DRIBBBLE('\uf17D'),
+        DROPBOX('\uf16B'),
+        DRUPAL('\uf1A9'),
+        EDIT('\uf044'),
+        EJECT('\uf052'),
+        ELLIPSIS_H('\uf141'),
+        ELLIPSIS_V('\uf142'),
+        EMPIRE('\uf1D1'),
+        ENVELOPE('\uf0E0'),
+        ENVELOPE_ALT('\uf003'),
+        ENVELOPE_SQUARE('\uf199'),
+        ERASER('\uf12D'),
+        EUR('\uf153'),
+        EURO('\uf153'),
+        EXCHANGE('\uf0EC'),
+        EXCLAMATION('\uf12A'),
+        EXCLAMATION_CIRCLE('\uf06A'),
+        EXCLAMATION_TRIANGLE('\uf071'),
+        EXPAND('\uf065'),
+        EXTERNAL_LINK('\uf08E'),
+        EXTERNAL_LINK_SQUARE('\uf14C'),
+        EYE('\uf06E'),
+        EYE_SLASH('\uf070'),
+        EYEDROPPER('\uf1FB'),
+        FACEBOOK('\uf09A'),
+        FACEBOOK_F('\uf09A'),
+        FACEBOOK_ALTFFICIAL('\uf230'),
+        FACEBOOK_SQUARE('\uf082'),
+        FAST_BACKWARD('\uf049'),
+        FAST_FORWARD('\uf050'),
+        FAX('\uf1AC'),
+        FEMALE('\uf182'),
+        FIGHTER_JET('\uf0FB'),
+        FILE('\uf15B'),
+        FILE_ARCHIVE_ALT('\uf1C6'),
+        FILE_AUDIO_ALT('\uf1C7'),
+        FILE_CODE_ALT('\uf1C9'),
+        FILE_EXCEL_ALT('\uf1C3'),
+        FILE_IMAGE_ALT('\uf1C5'),
+        FILE_MOVIE_ALT('\uf1C8'),
+        FILE_ALT('\uf016'),
+        FILE_PDF_ALT('\uf1C1'),
+        FILE_PHOTO_ALT('\uf1C5'),
+        FILE_PICTURE_ALT('\uf1C5'),
+        FILE_POWERPOINT_ALT('\uf1C4'),
+        FILE_SOUND_ALT('\uf1C7'),
+        FILE_TEXT('\uf15C'),
+        FILE_TEXT_ALT('\uf0F6'),
+        FILE_VIDEO_ALT('\uf1C8'),
+        FILE_WORD_ALT('\uf1C2'),
+        FILE_ZIP_ALT('\uf1C6'),
+        FILES_ALT('\uf0C5'),
+        FILM('\uf008'),
+        FILTER('\uf0B0'),
+        FIRE('\uf06D'),
+        FIRE_EXTINGUISHER('\uf134'),
+        FLAG('\uf024'),
+        FLAG_CHECKERED('\uf11E'),
+        FLAG_ALT('\uf11D'),
+        FLASH('\uf0E7'),
+        FLASK('\uf0C3'),
+        FLICKR('\uf16E'),
+        FLOPPY_ALT('\uf0C7'),
+        FOLDER('\uf07B'),
+        FOLDER_ALT('\uf114'),
+        FOLDER_OPEN('\uf07C'),
+        FOLDER_OPEN_ALT('\uf115'),
+        FONT('\uf031'),
+        FORUMBEE('\uf211'),
+        FORWARD('\uf04E'),
+        FOURSQUARE('\uf180'),
+        FROWN_ALT('\uf119'),
+        FUTBOL_ALT('\uf1E3'),
+        GAMEPAD('\uf11B'),
+        GAVEL('\uf0E3'),
+        GBP('\uf154'),
+        GE('\uf1D1'),
+        GEAR('\uf013'),
+        GEARS('\uf085'),
+        GENDERLESS('\uf1DB'),
+        GIFT('\uf06B'),
+        GIT('\uf1D3'),
+        GIT_SQUARE('\uf1D2'),
+        GITHUB('\uf09B'),
+        GITHUB_ALT('\uf113'),
+        GITHUB_SQUARE('\uf092'),
+        GITTIP('\uf184'),
+        GLASS('\uf000'),
+        GLOBE('\uf0AC'),
+        GOOGLE('\uf1A0'),
+        GOOGLE_PLUS('\uf0D5'),
+        GOOGLE_PLUS_SQUARE('\uf0D4'),
+        GOOGLE_WALLET('\uf1EE'),
+        GRADUATION_CAP('\uf19D'),
+        GRATIPAY('\uf184'),
+        GROUP('\uf0C0'),
+        H_SQUARE('\uf0FD'),
+        HACKER_NEWS('\uf1D4'),
+        HAND_ALT_DOWN('\uf0A7'),
+        HAND_ALT_LEFT('\uf0A5'),
+        HAND_ALT_RIGHT('\uf0A4'),
+        HAND_ALT_UP('\uf0A6'),
+        HDD_ALT('\uf0A0'),
+        HEADER('\uf1DC'),
+        HEADPHONES('\uf025'),
+        HEART('\uf004'),
+        HEART_ALT('\uf08A'),
+        HEARTBEAT('\uf21E'),
+        HISTORY('\uf1DA'),
+        HOME('\uf015'),
+        HOSPITAL_ALT('\uf0F8'),
+        HOTEL('\uf236'),
+        HTML5('\uf13B'),
+        ILS('\uf20B'),
+        IMAGE('\uf03E'),
+        INBOX('\uf01C'),
+        INDENT('\uf03C'),
+        INFO('\uf129'),
+        INFO_CIRCLE('\uf05A'),
+        INR('\uf156'),
+        INSTAGRAM('\uf16D'),
+        INSTITUTION('\uf19C'),
+        IOXHOST('\uf208'),
+        ITALIC('\uf033'),
+        JOOMLA('\uf1AA'),
+        JPY('\uf157'),
+        JSFIDDLE('\uf1CC'),
+        KEY('\uf084'),
+        KEYBOARD_ALT('\uf11C'),
+        KRW('\uf159'),
+        LANGUAGE('\uf1AB'),
+        LAPTOP('\uf109'),
+        LASTFM('\uf202'),
+        LASTFM_SQUARE('\uf203'),
+        LEAF('\uf06C'),
+        LEANPUB('\uf212'),
+        LEGAL('\uf0E3'),
+        LEMON_ALT('\uf094'),
+        LEVEL_DOWN('\uf149'),
+        LEVEL_UP('\uf148'),
+        LIFE_BOUY('\uf1CD'),
+        LIFE_BUOY('\uf1CD'),
+        LIFE_RING('\uf1CD'),
+        LIFE_SAVER('\uf1CD'),
+        LIGHTBULB_ALT('\uf0EB'),
+        LINE_CHART('\uf201'),
+        LINK('\uf0C1'),
+        LINKEDIN('\uf0E1'),
+        LINKEDIN_SQUARE('\uf08C'),
+        LINUX('\uf17C'),
+        LIST('\uf03A'),
+        LIST_ALT('\uf022'),
+        LIST_OL('\uf0CB'),
+        LIST_UL('\uf0CA'),
+        LOCATION_ARROW('\uf124'),
+        LOCK('\uf023'),
+        LONG_ARROW_DOWN('\uf175'),
+        LONG_ARROW_LEFT('\uf177'),
+        LONG_ARROW_RIGHT('\uf178'),
+        LONG_ARROW_UP('\uf176'),
+        MAGIC('\uf0D0'),
+        MAGNET('\uf076'),
+        MAIL_FORWARD('\uf064'),
+        MAIL_REPLY('\uf112'),
+        MAIL_REPLY_ALL('\uf122'),
+        MALE('\uf183'),
+        MAP_MARKER('\uf041'),
+        MARS('\uf222'),
+        MARS_DOUBLE('\uf227'),
+        MARS_STROKE('\uf229'),
+        MARS_STROKE_H('\uf22B'),
+        MARS_STROKE_V('\uf22A'),
+        MAXCDN('\uf136'),
+        MEANPATH('\uf20C'),
+        MEDIUM('\uf23A'),
+        MEDKIT('\uf0FA'),
+        MEH_ALT('\uf11A'),
+        MERCURY('\uf223'),
+        MICROPHONE('\uf130'),
+        MICROPHONE_SLASH('\uf131'),
+        MINUS('\uf068'),
+        MINUS_CIRCLE('\uf056'),
+        MINUS_SQUARE('\uf146'),
+        MINUS_SQUARE_ALT('\uf147'),
+        MOBILE('\uf10B'),
+        MOBILE_PHONE('\uf10B'),
+        MONEY('\uf0D6'),
+        MOON_ALT('\uf186'),
+        MORTAR_BOARD('\uf19D'),
+        MOTORCYCLE('\uf21C'),
+        MUSIC('\uf001'),
+        NAVICON('\uf0C9'),
+        NEUTER('\uf22C'),
+        NEWSPAPER_ALT('\uf1EA'),
+        OPENID('\uf19B'),
+        OUTDENT('\uf03B'),
+        PAGELINES('\uf18C'),
+        PAINT_BRUSH('\uf1FC'),
+        PAPER_PLANE('\uf1D8'),
+        PAPER_PLANE_ALT('\uf1D9'),
+        PAPERCLIP('\uf0C6'),
+        PARAGRAPH('\uf1DD'),
+        PASTE('\uf0EA'),
+        PAUSE('\uf04C'),
+        PAW('\uf1B0'),
+        PAYPAL('\uf1ED'),
+        PENCIL('\uf040'),
+        PENCIL_SQUARE('\uf14B'),
+        PENCIL_SQUARE_ALT('\uf044'),
+        PHONE('\uf095'),
+        PHONE_SQUARE('\uf098'),
+        PHOTO('\uf03E'),
+        PICTURE_ALT('\uf03E'),
+        PIE_CHART('\uf200'),
+        PIED_PIPER('\uf1A7'),
+        PIED_PIPER_ALT('\uf1A8'),
+        PINTEREST('\uf0D2'),
+        PINTEREST_P('\uf231'),
+        PINTEREST_SQUARE('\uf0D3'),
+        PLANE('\uf072'),
+        PLAY('\uf04B'),
+        PLAY_CIRCLE('\uf144'),
+        PLAY_CIRCLE_ALT('\uf01D'),
+        PLUG('\uf1E6'),
+        PLUS('\uf067'),
+        PLUS_CIRCLE('\uf055'),
+        PLUS_SQUARE('\uf0FE'),
+        PLUS_SQUARE_ALT('\uf196'),
+        POWER_OFF('\uf011'),
+        PRINT('\uf02F'),
+        PUZZLE_PIECE('\uf12E'),
+        QQ('\uf1D6'),
+        QRCODE('\uf029'),
+        QUESTION('\uf128'),
+        QUESTION_CIRCLE('\uf059'),
+        QUOTE_LEFT('\uf10D'),
+        QUOTE_RIGHT('\uf10E'),
+        RA('\uf1D0'),
+        RANDOM('\uf074'),
+        REBEL('\uf1D0'),
+        RECYCLE('\uf1B8'),
+        REDDIT('\uf1A1'),
+        REDDIT_SQUARE('\uf1A2'),
+        REFRESH('\uf021'),
+        REMOVE('\uf00D'),
+        RENREN('\uf18B'),
+        REORDER('\uf0C9'),
+        REPEAT('\uf01E'),
+        REPLY('\uf112'),
+        REPLY_ALL('\uf122'),
+        RETWEET('\uf079'),
+        RMB('\uf157'),
+        ROAD('\uf018'),
+        ROCKET('\uf135'),
+        ROTATE_LEFT('\uf0E2'),
+        ROTATE_RIGHT('\uf01E'),
+        ROUBLE('\uf158'),
+        RSS('\uf09E'),
+        RSS_SQUARE('\uf143'),
+        RUB('\uf158'),
+        RUBLE('\uf158'),
+        RUPEE('\uf156'),
+        SAVE('\uf0C7'),
+        SCISSORS('\uf0C4'),
+        SEARCH('\uf002'),
+        SEARCH_MINUS('\uf010'),
+        SEARCH_PLUS('\uf00E'),
+        SELLSY('\uf213'),
+        SEND('\uf1D8'),
+        SEND_ALT('\uf1D9'),
+        SERVER('\uf233'),
+        SHARE('\uf064'),
+        SHARE_ALT('\uf1E0'),
+        SHARE_ALT_SQUARE('\uf1E1'),
+        SHARE_SQUARE('\uf14D'),
+        SHARE_SQUARE_ALT('\uf045'),
+        SHEKEL('\uf20B'),
+        SHEQEL('\uf20B'),
+        SHIELD('\uf132'),
+        SHIP('\uf21A'),
+        SHIRTSINBULK('\uf214'),
+        SHOPPING_CART('\uf07A'),
+        SIGN_IN('\uf090'),
+        SIGN_OUT('\uf08B'),
+        SIGNAL('\uf012'),
+        SIMPLYBUILT('\uf215'),
+        SITEMAP('\uf0E8'),
+        SKYATLAS('\uf216'),
+        SKYPE('\uf17E'),
+        SLACK('\uf198'),
+        SLIDERS('\uf1DE'),
+        SLIDESHARE('\uf1E7'),
+        SMILE_ALT('\uf118'),
+        SOCCER_BALL_ALT('\uf1E3'),
+        SORT('\uf0DC'),
+        SORT_ALPHA_ASC('\uf15D'),
+        SORT_ALPHA_DESC('\uf15E'),
+        SORT_AMOUNT_ASC('\uf160'),
+        SORT_AMOUNT_DESC('\uf161'),
+        SORT_ASC('\uf0DE'),
+        SORT_DESC('\uf0DD'),
+        SORT_DOWN('\uf0DD'),
+        SORT_NUMERIC_ASC('\uf162'),
+        SORT_NUMERIC_DESC('\uf163'),
+        SORT_UP('\uf0DE'),
+        SOUNDCLOUD('\uf1BE'),
+        SPACE_SHUTTLE('\uf197'),
+        SPINNER('\uf110'),
+        SPOON('\uf1B1'),
+        SPOTIFY('\uf1BC'),
+        SQUARE('\uf0C8'),
+        SQUARE_ALT('\uf096'),
+        STACK_EXCHANGE('\uf18D'),
+        STACK_OVERFLOW('\uf16C'),
+        STAR('\uf005'),
+        STAR_HALF('\uf089'),
+        STAR_HALF_EMPTY('\uf123'),
+        STAR_HALF_FULL('\uf123'),
+        STAR_HALF_ALT('\uf123'),
+        STAR_ALT('\uf006'),
+        STEAM('\uf1B6'),
+        STEAM_SQUARE('\uf1B7'),
+        STEP_BACKWARD('\uf048'),
+        STEP_FORWARD('\uf051'),
+        STETHOSCOPE('\uf0F1'),
+        STOP('\uf04D'),
+        STREET_VIEW('\uf21D'),
+        STRIKETHROUGH('\uf0CC'),
+        STUMBLEUPON('\uf1A4'),
+        STUMBLEUPON_CIRCLE('\uf1A3'),
+        SUBSCRIPT('\uf12C'),
+        SUBWAY('\uf239'),
+        SUITCASE('\uf0F2'),
+        SUN_ALT('\uf185'),
+        SUPERSCRIPT('\uf12B'),
+        SUPPORT('\uf1CD'),
+        TABLE('\uf0CE'),
+        TABLET('\uf10A'),
+        TACHOMETER('\uf0E4'),
+        TAG('\uf02B'),
+        TAGS('\uf02C'),
+        TASKS('\uf0AE'),
+        TAXI('\uf1BA'),
+        TENCENT_WEIBO('\uf1D5'),
+        TERMINAL('\uf120'),
+        TEXT_HEIGHT('\uf034'),
+        TEXT_WIDTH('\uf035'),
+        TH('\uf00A'),
+        TH_LARGE('\uf009'),
+        TH_LIST('\uf00B'),
+        THUMB_TACK('\uf08D'),
+        THUMBS_DOWN('\uf165'),
+        THUMBS_ALT_DOWN('\uf088'),
+        THUMBS_ALT_UP('\uf087'),
+        THUMBS_UP('\uf164'),
+        TICKET('\uf145'),
+        TIMES('\uf00D'),
+        TIMES_CIRCLE('\uf057'),
+        TIMES_CIRCLE_ALT('\uf05C'),
+        TINT('\uf043'),
+        TOGGLE_DOWN('\uf150'),
+        TOGGLE_LEFT('\uf191'),
+        TOGGLE_OFF('\uf204'),
+        TOGGLE_ON('\uf205'),
+        TOGGLE_RIGHT('\uf152'),
+        TOGGLE_UP('\uf151'),
+        TRAIN('\uf238'),
+        TRANSGENDER('\uf224'),
+        TRANSGENDER_ALT('\uf225'),
+        TRASH('\uf1F8'),
+        TRASH_ALT('\uf014'),
+        TREE('\uf1BB'),
+        TRELLO('\uf181'),
+        TROPHY('\uf091'),
+        TRUCK('\uf0D1'),
+        TRY('\uf195'),
+        TTY('\uf1E4'),
+        TUMBLR('\uf173'),
+        TUMBLR_SQUARE('\uf174'),
+        TURKISH_LIRA('\uf195'),
+        TWITCH('\uf1E8'),
+        TWITTER('\uf099'),
+        TWITTER_SQUARE('\uf081'),
+        UMBRELLA('\uf0E9'),
+        UNDERLINE('\uf0CD'),
+        UNDO('\uf0E2'),
+        UNIVERSITY('\uf19C'),
+        UNLINK('\uf127'),
+        UNLOCK('\uf09C'),
+        UNLOCK_ALT('\uf13E'),
+        UNSORTED('\uf0DC'),
+        UPLOAD('\uf093'),
+        USD('\uf155'),
+        USER('\uf007'),
+        USER_MD('\uf0F0'),
+        USER_PLUS('\uf234'),
+        USER_SECRET('\uf21B'),
+        USER_TIMES('\uf235'),
+        USERS('\uf0C0'),
+        VENUS('\uf221'),
+        VENUS_DOUBLE('\uf226'),
+        VENUS_MARS('\uf228'),
+        VIACOIN('\uf237'),
+        VIDEO_CAMERA('\uf03D'),
+        VIMEO_SQUARE('\uf194'),
+        VINE('\uf1CA'),
+        VK('\uf189'),
+        VOLUME_DOWN('\uf027'),
+        VOLUME_OFF('\uf026'),
+        VOLUME_UP('\uf028'),
+        WARNING('\uf071'),
+        WECHAT('\uf1D7'),
+        WEIBO('\uf18A'),
+        WEIXIN('\uf1D7'),
+        WHATSAPP('\uf232'),
+        WHEELCHAIR('\uf193'),
+        WIFI('\uf1EB'),
+        WINDOWS('\uf17A'),
+        WON('\uf159'),
+        WORDPRESS('\uf19A'),
+        WRENCH('\uf0AD'),
+        XING('\uf168'),
+        XING_SQUARE('\uf169'),
+        YAHOO('\uf19E'),
+        YELP('\uf1E9'),
+        YEN('\uf157'),
+        YOUTUBE('\uf167'),
+        YOUTUBE_PLAY('\uf16A'),
+        YOUTUBE_SQUARE('\uf166');
+
+        private final char ch;
+
+        /**
+         * Creates a named Glyph mapped to the given character
+         * @param ch
+         */
+        Glyph( char ch ) {
+            this.ch = ch;
+        }
+
+        @Override
+        public char getChar() {
+            return ch;
+        }
+    };
+
+    /**
+     * Do not call this constructor directly - instead access the
+     * {@link FontAwesome.Glyph} public static enumeration method to create the glyph nodes), or
+     * use the {@link GlyphFontRegistry} class to get access.
+     *
+     * Note: Do not remove this public constructor since it is used by the service loader!
+     */
+    public FontAwesome() {
+        this("http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/fonts/fontawesome-webfont.ttf"); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates a new FontAwesome instance which uses the provided font source.
+     * @param url
+     */
+    public FontAwesome(String url){
+        super(fontName, 14, url, true);
+        registerAll(Arrays.asList(Glyph.values()));
+    }
+
+    /**
+     * Creates a new FontAwesome instance which uses the provided font source.
+     * @param is
+     */
+    public FontAwesome(InputStream is){
+        super(fontName, 14, is, true);
+        registerAll(Arrays.asList(Glyph.values()));
+    }
+
+}
diff --git a/src/org/controlsfx/glyphfont/Glyph.java b/src/org/controlsfx/glyphfont/Glyph.java
new file mode 100644
index 0000000000000000000000000000000000000000..8bb8c729e3ecc6b088b85a3ad2a202182ea13e42
--- /dev/null
+++ b/src/org/controlsfx/glyphfont/Glyph.java
@@ -0,0 +1,350 @@
+/**
+ * Copyright (c) 2013, 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.glyphfont;
+
+import java.util.Optional;
+
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.collections.ObservableList;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.paint.*;
+import javafx.scene.text.Font;
+
+import org.controlsfx.control.action.Action;
+import org.controlsfx.tools.Duplicatable;
+
+/**
+ * Represents one glyph from the font.
+ * The glyph is actually a label showing one character from the specified font. It can be used as 'graphic' on any UI
+ * control or {@link Action}. It can also directly be used in FXML.
+ *
+ * Examples:
+ *
+ * <pre>{@code
+ * new Button("", new Glyph("FontAwesome", "BEER"))
+ * }</pre>
+ *
+ * <pre>{@code
+ * new Button("", new Glyph("FontAwesome", FontAwesome.Glyph.BEER))
+ * }</pre>
+ *
+ * Thy Glyph-Class also offers a fluent API to customize the look of the Glyph.
+ * For example, you can set the color {@link #color(javafx.scene.paint.Color)} or
+ * also add effects such as {@link #useHoverEffect()}
+ *
+ * <p>An ability to retrieve glyph node by combination of font name and glyph name
+ * extends to the {@link org.controlsfx.control.action.ActionProxy} graphic attribute, where the "font&gt;"
+ * prefix should be used. For more information see {@link org.controlsfx.control.action.ActionProxy}.
+ *
+ */
+public class Glyph extends Label implements Duplicatable<Glyph> {
+
+    /***************************************************************************
+     *                                                                         *
+     * Static creators                                                         *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Retrieve glyph by font name and glyph name using one string
+     * where font name an glyph name are separated by pipe.
+     *
+     * @param fontAndGlyph The font and glyph separated by a pipe. Example: "FontAwesome|STAR"
+     * @return A instance of a Glyph node
+     */
+    public static Glyph create(String fontAndGlyph) {
+        String[] args = fontAndGlyph.split("\\|"); //$NON-NLS-1$
+        return new Glyph(args[0], args[1]);
+    }
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Private fields                                                          *
+     *                                                                         *
+     **************************************************************************/
+
+    public final static String DEFAULT_CSS_CLASS = "glyph-font";    //$NON-NLS-1$
+    public final static String STYLE_GRADIENT = "gradient";         //$NON-NLS-1$
+    public final static String STYLE_HOVER_EFFECT = "hover-effect"; //$NON-NLS-1$
+
+    private final ObjectProperty<Object> icon = new SimpleObjectProperty<>();
+
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Empty Constructor (used by FXML)
+     */
+    public Glyph(){
+        getStyleClass().add(DEFAULT_CSS_CLASS);
+
+        icon.addListener(x -> updateIcon());
+        fontProperty().addListener(x -> updateIcon());
+    }
+
+    /**
+     * Creates a new Glyph
+     * @param fontFamily The family name of the font. Example: "FontAwesome"
+     * @param unicode The Unicode character of the glyph
+     */
+    public Glyph(String fontFamily, char unicode) {
+        this();
+        setFontFamily(fontFamily);
+        setTextUnicode(unicode);
+    }
+
+    /**
+     * Creates a new Glyph
+     * @param fontFamily The family name of the font. Example: "FontAwesome"
+     * @param icon The icon - which can be the name (String) or Enum value.
+     *             Example: FontAwesome.Glyph.BEER
+     */
+    public Glyph(String fontFamily, Object icon) {
+        this();
+        setFontFamily(fontFamily);
+        setIcon(icon);
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Sets the glyph icon font family
+     * @param fontFamily A font family name
+     * @return Returns this instance for fluent API
+     */
+    public Glyph fontFamily(String fontFamily){
+        setFontFamily(fontFamily);
+        return this;
+    }
+
+    /**
+     * Sets the glyph color
+     * @param color
+     * @return Returns this instance for fluent API
+     */
+    public Glyph color(Color color){
+        setColor(color);
+        return this;
+    }
+
+    /**
+     * Sets glyph size
+     * @param size
+     * @return Returns this instance for fluent API
+     */
+    public Glyph size(double size) {
+        setFontSize(size);
+        return this;
+    }
+
+    /**
+     * Sets glyph size using size factor based on default font size
+     * @param factor
+     * @return Returns this instance for fluent API
+     */
+    public Glyph sizeFactor(int factor) {
+    	Optional.ofNullable(GlyphFontRegistry.font(getFont().getFamily())).ifPresent( glyphFont ->{
+    		setFontSize(glyphFont.getDefaultSize()* (factor < 1? 1: factor));
+    	});
+    	return this;
+    }
+
+    
+
+    /**
+     * Adds the hover effect style
+     * @return Returns this instance for fluent API
+     */
+    public Glyph useHoverEffect(){
+        this.getStyleClass().add(Glyph.STYLE_HOVER_EFFECT);
+        return this;
+    }
+
+    /**
+     * Adds the gradient effect style
+     * @return Returns this instance for fluent API
+     */
+    public Glyph useGradientEffect(){
+
+        if(getTextFill() instanceof Color){
+            Color currentColor = (Color)getTextFill();
+
+            /*
+             TODO
+             Do this in code:
+            -fx-text-fill: linear-gradient(to bottom, derive(-fx-text-fill,20%) 10%, derive(-fx-text-fill,-40%) 80%);
+             */
+            Stop[] stops = new Stop[] { new Stop(0, Color.BLACK), new Stop(1, currentColor)};
+            LinearGradient lg1 = new LinearGradient(0, 0, 1, 0, true, CycleMethod.NO_CYCLE, stops);
+            setTextFill(lg1);
+        }
+
+        this.getStyleClass().add(Glyph.STYLE_GRADIENT);
+        return this;
+    }
+
+
+    /**
+     * Allows glyph duplication. Since in the JavaFX scenegraph it is not possible to insert the same
+     * {@link Node} in multiple locations at the same time, this method allows for glyph reuse in several places
+     */
+    @Override public Glyph duplicate() {
+        Paint color = getTextFill();
+        Object icon = getIcon();
+        ObservableList<String> classes = getStyleClass();
+        return new Glyph(){{
+            setIcon(icon);
+            setTextFill(color);
+            getStyleClass().addAll(classes);
+        }}
+                .fontFamily(getFontFamily())
+                .size(getFontSize());
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Properties                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Sets the font family of this glyph
+     * Font size is reset to default glyph font size
+     */
+    public void setFontFamily(String family){
+        if( !getFont().getFamily().equals(family)){
+        	Optional.ofNullable(GlyphFontRegistry.font(family)).ifPresent( glyphFont -> {
+        		glyphFont.ensureFontIsLoaded(); // Make sure font is loaded 
+        		Font newFont = Font.font(family, glyphFont.getDefaultSize()); // Reset to default font size
+                setFont(newFont);
+        	});
+        }
+    }
+
+    /**
+     * Gets the font family of this glyph
+     */
+    public String getFontFamily(){
+        return getFont().getFamily();
+    }
+
+    /**
+     * Sets the font size of this glyph
+     */
+    public void setFontSize(double size){
+        Font newFont = Font.font(getFont().getFamily(), size);
+        setFont(newFont);
+    }
+
+    /**
+     * Gets the font size of this glyph
+     */
+    public double getFontSize(){
+        return getFont().getSize();
+    }
+
+    /**
+     * Set the Color of this Glyph
+     */
+    public void setColor(Color color){
+        setTextFill(color);
+    }
+
+    /**
+     * The icon name property.
+     *
+     * This must either be a Glyph-Name (either string or enum value) known by the GlyphFontRegistry.
+     * Alternatively, you can directly submit a unicode character here.
+     */
+    public ObjectProperty<Object> iconProperty(){
+        return icon;
+    }
+
+    /**
+     * Set the icon to display.
+     * @param iconValue This can either be the Glyph-Name, Glyph-Enum Value or a unicode character representing the sign.
+     */
+    public void setIcon(Object iconValue){
+        icon.set(iconValue);
+    }
+
+    public Object getIcon(){
+        return icon.get();
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Private methods                                                         *
+     *                                                                         *
+     **************************************************************************/
+
+
+    /**
+     * This updates the text with the correct unicode value
+     * so that the desired icon is displayed.
+     */
+    private void updateIcon(){
+
+        Object iconValue = getIcon();
+
+        if(iconValue != null) {
+            if(iconValue instanceof Character){
+                setTextUnicode((Character)iconValue);
+            }else {
+                GlyphFont glyphFont = GlyphFontRegistry.font(getFontFamily());
+                if (glyphFont != null) {
+                    String name = iconValue.toString();
+                    Character unicode = glyphFont.getCharacter(name);
+                    if (unicode != null) {
+                        setTextUnicode(unicode);
+                    } else {
+                        // Could not find a icon with this name
+                        setText(name);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the given char as text
+     * @param unicode
+     */
+    private void setTextUnicode(char unicode){
+        setText(String.valueOf(unicode));
+    }
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/glyphfont/GlyphFont.java b/src/org/controlsfx/glyphfont/GlyphFont.java
new file mode 100644
index 0000000000000000000000000000000000000000..ea355cd0f9387ab5b5043d2e03ceb3ef0668ff13
--- /dev/null
+++ b/src/org/controlsfx/glyphfont/GlyphFont.java
@@ -0,0 +1,245 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.glyphfont;
+
+import com.sun.javafx.css.StyleManager;
+import javafx.scene.text.Font;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *  Represents a glyph font, which can be loaded locally or from a specified URL.
+ *  {@link Glyph}s can be created easily using specified character defined in the
+ *  font. For example, &#92;uf013 in FontAwesome is used to represent
+ *  a gear icon.
+ *
+ *  <p>To simplify glyph customization, methods can be chained, for example:
+ *
+ *  <pre>
+ *  Glyph glyph = fontAwesome.create('&#92;uf013').size(28).color(Color.RED); //GEAR
+ *  </pre>
+ *
+ *  <p>Here's a screenshot of two font packs being used to render images into
+ *  JavaFX Button controls:
+ *
+ * <br>
+ * <center><img src="glyphFont.png" alt="Screenshot of GlyphFont"></center>
+ */
+public class GlyphFont {
+
+    static {
+        StyleManager.getInstance().addUserAgentStylesheet(
+                GlyphFont.class.getResource("glyphfont.css").toExternalForm()); //$NON-NLS-1$
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Private fields                                                          *
+     *                                                                         *
+     **************************************************************************/
+
+    private final Map<String, Character> namedGlyphs = new HashMap<>();
+    private final Runnable fontLoader;
+    private final String fontName;
+    private final double defaultSize;
+
+    private boolean  fontLoaded = false;
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Loads glyph font from specified {@link InputStream}
+     * @param fontName glyph font name
+     * @param defaultSize default font size
+     * @param in input stream to load the font from
+     */
+    public GlyphFont( String fontName, int defaultSize, final InputStream in) {
+        this(fontName, defaultSize, in, false);
+    }
+
+    /**
+     * Load glyph font from specified URL.
+     * Example for a local file:
+     * "file:///C:/Users/Bob/Fonts/icomoon.ttf"
+     * "file:///Users/Bob/Fonts/icomoon.ttf"
+     *
+     * @param fontName glyph font name
+     * @param defaultSize default font size
+     * @param urlStr A URL to load the font from
+     */
+    public GlyphFont( String fontName, int defaultSize, final String urlStr) {
+        this(fontName, defaultSize, urlStr, false);
+    }
+
+    /**
+     * Loads glyph font from specified {@link InputStream}
+     * @param fontName glyph font name
+     * @param defaultSize default font size
+     * @param in input stream to load the font from
+     * @param lazyLoad If true, the font will only be loaded when accessed
+     */
+    public GlyphFont( String fontName, int defaultSize, final InputStream in, boolean lazyLoad) {
+        this(fontName, defaultSize, () -> {
+            Font.loadFont(in, -1);
+        }, lazyLoad);
+    }
+
+    /**
+     * Load glyph font from specified URL.
+     * Example for a local file:
+     * "file:///C:/Users/Bob/Fonts/icomoon.ttf"
+     * "file:///Users/Bob/Fonts/icomoon.ttf"
+     *
+     * @param fontName glyph font name
+     * @param defaultSize default font size
+     * @param urlStr A URL to load the font from
+     * @param lazyLoad If true, the font will only be loaded when accessed
+     */
+    public GlyphFont( String fontName, int defaultSize, final String urlStr, boolean lazyLoad) {
+        this(fontName, defaultSize, () -> {
+            Font.loadFont(urlStr, -1);
+        }, lazyLoad);
+    }
+
+    /**
+     * Creates a GlyphFont
+     * @param fontName
+     * @param defaultSize
+     * @param fontLoader
+     * @param lazyLoad
+     */
+    private GlyphFont(String fontName, int defaultSize, Runnable fontLoader, boolean lazyLoad){
+        this.fontName = fontName;
+        this.defaultSize = defaultSize;
+        this.fontLoader = fontLoader;
+
+        if(!lazyLoad){
+            ensureFontIsLoaded();
+        }
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Returns font name
+     * @return font name
+     */
+    public String getName() {
+        return fontName;
+    }
+
+    /**
+     * Returns the default font size
+     * @return default font size
+     */
+    public double getDefaultSize() {
+        return defaultSize;
+    }
+
+
+    /**
+     * Creates an instance of {@link Glyph} using specified font character
+     * @param character font character
+     * @return instance of {@link Glyph}
+     */
+    public Glyph create(char character) {
+        return new Glyph(fontName, character);
+    }
+
+    /**
+     * Creates an instance of {@link Glyph} using glyph name
+     * @param glyphName glyph name
+     * @return glyph by its name or null if name is not found
+     */
+    public Glyph create(String glyphName) {
+        return new Glyph(fontName, glyphName);
+    }
+
+    /**
+     *  Creates an instance of {@link Glyph} using a known Glyph enum value
+     * @param glyph
+     */
+    public Glyph create(Enum<?> glyph) {
+        return new Glyph(fontName, glyph);
+    }
+
+    /**
+     * Returns the character code which is mapped to this Name.
+     * If no match is found, NULL is returned.
+     * @param glyphName
+     */
+    public Character getCharacter(String glyphName){
+        return namedGlyphs.get(glyphName.toUpperCase());
+    }
+
+
+    /**
+     * Registers all given characters with their name.
+     * @param namedCharacters
+     */
+    public void registerAll(Iterable<? extends INamedCharacter> namedCharacters){
+        for (INamedCharacter e:  namedCharacters) {
+            register(e.name(), e.getChar());
+        }
+    }
+
+    /**
+     * Registers the given name-character mapping
+     * @param name
+     * @param character
+     */
+    public void register(String name, Character character){
+        namedGlyphs.put(name.toUpperCase(), character);
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Internal methods                                                        *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Ensures that the font is loaded
+     */
+    synchronized void ensureFontIsLoaded(){
+        if ( !fontLoaded ) {
+            fontLoader.run();
+            fontLoaded = true;
+        }
+    }
+}
diff --git a/src/org/controlsfx/glyphfont/GlyphFontRegistry.java b/src/org/controlsfx/glyphfont/GlyphFontRegistry.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc9d433d561308f6d09b5e18b7d6f0a510d84c16
--- /dev/null
+++ b/src/org/controlsfx/glyphfont/GlyphFontRegistry.java
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2013,2014 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.glyphfont;
+
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+/**
+ * The glyph font registry automatically registers available fonts using a
+ * {@link ServiceLoader} facility, however it is also possible to register
+ * glyph fonts manually using the provided
+ * {@link GlyphFontRegistry#register(GlyphFont)} method.
+ *
+ * <p>Once registered, fonts can be requested by name using the
+ * {@link GlyphFontRegistry#font(String)} method.
+ *
+ * Please refer to the {@link GlyphFont} documentation
+ * to learn how to use a font.
+ *
+ */
+public final class GlyphFontRegistry {
+
+    /***************************************************************************
+     *                                                                         *
+     * Private fields                                                          *
+     *                                                                         *
+     **************************************************************************/
+
+    private static Map<String, GlyphFont> fontMap = new HashMap<>();
+
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    static {
+        // find all classes that implement GlyphFont and register them now
+        ServiceLoader<GlyphFont> loader = ServiceLoader.load(GlyphFont.class);
+        for (GlyphFont font : loader) {
+            GlyphFontRegistry.register(font);
+        }
+    }
+
+    /**
+     * Private constructor since static class
+     */
+    private GlyphFontRegistry() {
+        // no-op
+    }
+
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Registers the specified font as default GlyphFont
+     * @param familyName The name of this font.
+     * @param uri The location where it can be loaded from.
+     * @param defaultSize The default font size
+     */
+    public static void register(String familyName, String uri, int defaultSize){
+        register(new GlyphFont(familyName, defaultSize, uri));
+    }
+
+    /**
+     * Registers the specified font as default GlyphFont
+     * @param familyName The name of this font.
+     * @param in Inputstream of the font data
+     * @param defaultSize The default font size
+     */
+    public static void register(String familyName, InputStream in, int defaultSize){
+        register(new GlyphFont(familyName, defaultSize, in));
+    }
+
+    /**
+     * Registers the specified font
+     * @param font
+     */
+    public static void register( GlyphFont font ) {
+        if (font != null ) {
+            fontMap.put( font.getName(), font );
+        }
+    }
+
+    /**
+     * Retrieve font by its family name
+     * @param familyName family name of the font
+     * @return font or null if not found
+     */
+    public static GlyphFont font( String familyName ) {
+        GlyphFont font = fontMap.get(familyName);
+        if(font != null) {
+            font.ensureFontIsLoaded();
+        }
+        return font;
+    }
+}
diff --git a/src/org/controlsfx/glyphfont/INamedCharacter.java b/src/org/controlsfx/glyphfont/INamedCharacter.java
new file mode 100644
index 0000000000000000000000000000000000000000..60b7069d174edb475fe6449ba102ddd5da708b4f
--- /dev/null
+++ b/src/org/controlsfx/glyphfont/INamedCharacter.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.glyphfont;
+
+/**
+ * Represents a named character.
+ * This interface is usually implemented by a Enum
+ * which holds all characters of a specific font.
+ */
+public interface INamedCharacter {
+    /**
+     * Gets the name of this character
+     */
+    String name();
+
+    /**
+     * Gets the character value
+     */
+    char getChar();
+}
diff --git a/src/org/controlsfx/glyphfont/glyphfont.css b/src/org/controlsfx/glyphfont/glyphfont.css
new file mode 100644
index 0000000000000000000000000000000000000000..2803ef35107840434a1dc20c0ced03f8c2e0cf28
--- /dev/null
+++ b/src/org/controlsfx/glyphfont/glyphfont.css
@@ -0,0 +1,16 @@
+
+.glyph-font {
+
+}
+
+.glyph-font.gradient{
+    -fx-effect: innershadow( three-pass-box , derive(-fx-text-fill,-70%) , 0.1em, 0.0 , 0.07em, 0.07em );
+}
+
+.glyph-font.hover-effect:hover{
+    -fx-effect: dropshadow( three-pass-box , derive(-fx-text-fill,0%) , 0.01em, 0.0 , 0, 0);
+}
+
+.glyph-font.hover-effect:selected{
+    -fx-effect: dropshadow( three-pass-box , derive(-fx-text-fill,0%) , 0.01em, 0.0 , 0, 0);
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/glyphfont/package-info.java b/src/org/controlsfx/glyphfont/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..a4cee1649394f4789de25cbde2a6127c2aef1da1
--- /dev/null
+++ b/src/org/controlsfx/glyphfont/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * A package containing a number of useful code related to loading and using
+ * font packs whose characters are actually images.
+ */
+package org.controlsfx.glyphfont;
\ No newline at end of file
diff --git a/src/org/controlsfx/property/BeanProperty.java b/src/org/controlsfx/property/BeanProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..341525347e98d8e8a957267f5f36717277dd6473
--- /dev/null
+++ b/src/org/controlsfx/property/BeanProperty.java
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2013, 2015, 2016 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.property;
+
+import java.beans.FeatureDescriptor;
+import java.beans.PropertyDescriptor;
+import java.beans.PropertyVetoException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Optional;
+
+import org.controlsfx.control.PropertySheet;
+import org.controlsfx.control.PropertySheet.Item;
+import org.controlsfx.property.editor.PropertyEditor;
+
+import impl.org.controlsfx.i18n.Localization;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.Alert;
+
+/**
+ * A convenience class for creating a {@link Item} for use in the
+ * {@link PropertySheet} control based on a property belonging to a
+ * JavaBean - simply provide a {@link PropertyDescriptor} and the rest will be
+ * taken care of automatically.
+ *
+ * @see Item
+ * @see PropertySheet
+ * @see PropertyDescriptor
+ */
+public class BeanProperty implements PropertySheet.Item {
+
+    /**
+     * Unique identifier to provide a custom category label within
+     * {@link PropertySheet.Item#getCategory()}.
+     *
+     * How to use it: with a PropertyDescriptor, provide the custom category
+     * through a a named attribute
+     * {@link FeatureDescriptor#setValue(String, Object)}.
+     *
+     * <pre>
+     * final PropertyDescriptor propertyDescriptor = new PropertyDescriptor("yourProperty", YourBean.class);
+     * propertyDescriptor.setDisplayName("Your Display Name");
+     * propertyDescriptor.setShortDescription("Your explanation about this property.");
+     * // then provide a custom category
+     * propertyDescriptor.setValue(BeanProperty.CATEGORY_LABEL_KEY, "Your custom category");
+     * </pre>
+     */
+    public static final String CATEGORY_LABEL_KEY = "propertysheet.item.category.label";
+
+    private final Object bean;
+    private final PropertyDescriptor beanPropertyDescriptor;
+    private final Method readMethod;
+    private boolean editable = true;
+    private Optional<ObservableValue<? extends Object>> observableValue = Optional.empty();
+
+    public BeanProperty(final Object bean, final PropertyDescriptor propertyDescriptor) {
+        this.bean = bean;
+        this.beanPropertyDescriptor = propertyDescriptor;
+        this.readMethod = propertyDescriptor.getReadMethod();
+        if (this.beanPropertyDescriptor.getWriteMethod() == null) {
+            this.setEditable(false);
+        }
+
+        this.findObservableValue();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getName() {
+        return this.beanPropertyDescriptor.getDisplayName();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getDescription() {
+        return this.beanPropertyDescriptor.getShortDescription();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Class<?> getType() {
+        return this.beanPropertyDescriptor.getPropertyType();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object getValue() {
+        try {
+            return this.readMethod.invoke(this.bean);
+        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void setValue(final Object value) {
+        final Method writeMethod = this.beanPropertyDescriptor.getWriteMethod();
+        if ( writeMethod != null ) {
+            try {
+                writeMethod.invoke(this.bean, value);
+            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                e.printStackTrace();
+            } catch (final Throwable e) {
+                if (e instanceof PropertyVetoException) {
+                    final Alert alert = new Alert(Alert.AlertType.ERROR);
+                    alert.setTitle(Localization.localize(Localization.asKey("bean.property.change.error.title")));//$NON-NLS-1$
+                    alert.setHeaderText(Localization.localize(Localization.asKey("bean.property.change.error.masthead")));//$NON-NLS-1$
+                    alert.setContentText(e.getLocalizedMessage());
+                    alert.showAndWait();
+                } else {
+                    throw e;
+                }
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getCategory() {
+        String category = (String) this.beanPropertyDescriptor.getValue(BeanProperty.CATEGORY_LABEL_KEY);
+
+        // fall back to default behavior if there is no category provided.
+        if (category == null) {
+            category = Localization.localize(Localization.asKey(this.beanPropertyDescriptor.isExpert()
+                    ? "bean.property.category.expert" : "bean.property.category.basic")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        return category;
+    }
+
+    /**
+     * @return The object passed in to the constructor of the BeanProperty.
+     */
+    public Object getBean() {
+        return this.bean;
+    }
+
+    /**
+     * @return The {@link PropertyDescriptor} passed in to the constructor of
+     * the BeanProperty.
+     */
+    public PropertyDescriptor getPropertyDescriptor() {
+        return this.beanPropertyDescriptor;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings({ "unchecked" })
+    @Override public Optional<Class<? extends PropertyEditor<?>>> getPropertyEditorClass() {
+
+        if ((this.beanPropertyDescriptor.getPropertyEditorClass() != null) &&
+                PropertyEditor.class.isAssignableFrom(this.beanPropertyDescriptor.getPropertyEditorClass())) {
+
+            return Optional.of((Class<PropertyEditor<?>>)this.beanPropertyDescriptor.getPropertyEditorClass());
+        }
+
+        return Item.super.getPropertyEditorClass();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isEditable() {
+        return this.editable;
+    }
+
+    /**
+     * @param editable Whether this property should be editable in the PropertySheet.
+     */
+    public void setEditable(final boolean editable) {
+        this.editable = editable;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Optional<ObservableValue<? extends Object>> getObservableValue() {
+        return this.observableValue;
+    }
+
+    private void findObservableValue() {
+        try {
+            final String propName = this.beanPropertyDescriptor.getName() + "Property";
+            final Method m = this.getBean().getClass().getMethod(propName);
+            final Object val = m.invoke(this.getBean());
+            if ((val != null) && (val instanceof ObservableValue)) {
+                this.observableValue = Optional.of((ObservableValue<?>) val);
+            }
+        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+            //Logger.getLogger(BeanProperty.class.getName()).log(Level.SEVERE, null, ex);
+            // ignore it...
+        }
+    }
+}
diff --git a/src/org/controlsfx/property/BeanPropertyUtils.java b/src/org/controlsfx/property/BeanPropertyUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..b88093bc5eec9c3a8a933b853a9e79b9685d9224
--- /dev/null
+++ b/src/org/controlsfx/property/BeanPropertyUtils.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.property;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.util.function.Predicate;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+
+import org.controlsfx.control.PropertySheet;
+import org.controlsfx.control.PropertySheet.Item;
+
+/**
+ * Convenience utility class for creating {@link PropertySheet} instances based
+ * on a JavaBean.
+ */
+public final class BeanPropertyUtils {
+
+    private BeanPropertyUtils() {
+        // no op
+    }
+
+    /**
+     * Given a JavaBean, this method will return a list of {@link Item} intances,
+     * which may be directly placed inside a {@link PropertySheet} (via its
+     * {@link PropertySheet#getItems() items list}.
+     * <p>
+     * This method will not return read-only properties.
+     * 
+     * @param bean The JavaBean that should be introspected and be editable via
+     *      a {@link PropertySheet}.
+     * @return A list of {@link Item} instances representing the properties of the
+     *      JavaBean.
+     */
+    public static ObservableList<Item> getProperties(final Object bean) {
+        return getProperties(bean, (p) -> {return true;} );
+    }
+    
+    /**
+     * Given a JavaBean, this method will return a list of {@link Item} intances,
+     * which may be directly placed inside a {@link PropertySheet} (via its
+     * {@link PropertySheet#getItems() items list}.
+     * 
+     * @param bean The JavaBean that should be introspected and be editable via
+     *      a {@link PropertySheet}.
+     * @param test Predicate to test whether the property should be included in the 
+     *      list of results.
+     * @return A list of {@link Item} instances representing the properties of the
+     *      JavaBean.
+     */
+    public static ObservableList<Item> getProperties(final Object bean, Predicate<PropertyDescriptor> test) {
+        ObservableList<Item> list = FXCollections.observableArrayList();
+        try {
+            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(), Object.class);
+            for (PropertyDescriptor p : beanInfo.getPropertyDescriptors()) {
+                if (test.test(p)) {
+                    list.add(new BeanProperty(bean, p));
+                }
+            }
+        } catch (IntrospectionException e) {
+            e.printStackTrace();
+        }
+
+        return list;
+    }
+    
+}
diff --git a/src/org/controlsfx/property/editor/AbstractObjectField.java b/src/org/controlsfx/property/editor/AbstractObjectField.java
new file mode 100644
index 0000000000000000000000000000000000000000..d6f394135c09736515675b4a0bc65c456b6a9487
--- /dev/null
+++ b/src/org/controlsfx/property/editor/AbstractObjectField.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.property.editor;
+
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.StringProperty;
+import javafx.scene.Cursor;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseButton;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.StackPane;
+
+import org.controlsfx.control.textfield.CustomTextField;
+
+// package-private for now...
+abstract class AbstractObjectField<T> extends HBox {
+
+    //TODO: Replace with CSS
+    private static final Image image = new Image(AbstractObjectField.class.getResource("/org/controlsfx/control/open-editor.png").toExternalForm()); //$NON-NLS-1$
+
+    private final CustomTextField textField = new CustomTextField();
+
+    private ObjectProperty<T> objectProperty = new SimpleObjectProperty<>();
+
+    public AbstractObjectField() {
+        super(1);
+        textField.setEditable(false);
+        textField.setFocusTraversable(false);
+
+        StackPane button = new StackPane(new ImageView(image));
+        button.setCursor(Cursor.DEFAULT);
+
+        button.setOnMouseReleased(e -> {
+            if ( MouseButton.PRIMARY == e.getButton() ) {
+                final T result = edit(objectProperty.get());
+                if (result != null) {
+                    objectProperty.set(result);
+                }
+            }
+        });
+
+        textField.setRight(button);
+        getChildren().add(textField);
+        HBox.setHgrow(textField, Priority.ALWAYS);
+
+        objectProperty.addListener((o, oldValue, newValue) -> textProperty().set(objectToString(newValue)));
+    }
+
+    protected StringProperty textProperty() {
+        return textField.textProperty();
+    }
+
+    public ObjectProperty<T> getObjectProperty() {
+        return objectProperty;
+    }
+
+    protected String objectToString(T object) {
+        return object == null ? "" : object.toString(); //$NON-NLS-1$
+    }
+
+    protected abstract Class<T> getType();
+
+    protected abstract T edit(T object);
+}
diff --git a/src/org/controlsfx/property/editor/AbstractPropertyEditor.java b/src/org/controlsfx/property/editor/AbstractPropertyEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a3cc8020fdfd7dce5927df37726dfe53318f9a6
--- /dev/null
+++ b/src/org/controlsfx/property/editor/AbstractPropertyEditor.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.property.editor;
+
+import javafx.beans.value.ObservableValue;
+import javafx.scene.Node;
+
+import org.controlsfx.control.PropertySheet.Item;
+
+/**
+ * An abstract implementation of the {@link PropertyEditor} interface.
+ *
+ * @param <T> The type of the property being edited.
+ * @param <C> The type of Node that is used to edit this property.
+ */
+public abstract class AbstractPropertyEditor<T, C extends Node> implements PropertyEditor<T> {
+    
+    /**************************************************************************
+     * 
+     * Private fields
+     * 
+     **************************************************************************/
+
+    private final Item property;
+    private final C control;
+    private boolean suspendUpdate;
+    
+    
+    /**************************************************************************
+     * 
+     * Constructors
+     * 
+     **************************************************************************/
+    
+    /**
+     * Creates an editable AbstractPropertyEditor instance for the given property
+     * using the given editing control.
+     * 
+     * @param property The property that the instance is responsible for editing.
+     * @param control The control that is responsible for editing the property.
+     */
+    public AbstractPropertyEditor(Item property, C control) {
+        this(property, control, ! property.isEditable());
+    }
+    
+    /**
+     * Creates an AbstractPropertyEditor instance for the given property
+     * using the given editing control. It may be read-only or editable, based
+     * on the readonly boolean parameter being true or false.
+     * 
+     * @param property The property that the instance is responsible for editing.
+     * @param control The control that is responsible for editing the property.
+     * @param readonly Specifies whether the editor should allow input or not.
+     */
+    public AbstractPropertyEditor(Item property, C control, boolean readonly) {
+        this.control = control;
+        this.property = property;
+        if (! readonly) {
+            getObservableValue().addListener((ObservableValue<? extends Object> o, Object oldValue, Object newValue) -> {
+                if (! suspendUpdate) {
+                    suspendUpdate = true;
+                    AbstractPropertyEditor.this.property.setValue(getValue());
+                    suspendUpdate = false;
+                }
+            });
+            
+            if (property.getObservableValue().isPresent()) {
+                property.getObservableValue().get().addListener((ObservableValue<? extends Object> o, Object oldValue, Object newValue) -> {
+                    if (! suspendUpdate) {
+                        suspendUpdate = true;
+                        AbstractPropertyEditor.this.setValue((T) property.getValue());
+                        suspendUpdate = false;
+                    }
+                });
+            }
+            
+        }
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Public API
+     * 
+     **************************************************************************/
+    
+    /**
+     * Returns an {@link ObservableValue} of the property that this property
+     * editor is responsible for editing. This is the editor's value, e.g. a 
+     * TextField's textProperty().
+     */
+    protected abstract ObservableValue<T> getObservableValue();
+    
+    /**
+     * Returns the property that this property editor is responsible for editing.
+     */
+    public final Item getProperty() {
+        return property;
+    }
+        
+    /**
+     * {@inheritDoc}
+     */
+    @Override public C getEditor() {
+        return control;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override public T getValue() {
+        return getObservableValue().getValue();
+    }
+}
diff --git a/src/org/controlsfx/property/editor/DefaultPropertyEditorFactory.java b/src/org/controlsfx/property/editor/DefaultPropertyEditorFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..36b483b67d60fff2cee5835e42a5564a9712c424
--- /dev/null
+++ b/src/org/controlsfx/property/editor/DefaultPropertyEditorFactory.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.property.editor;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.LocalDate;
+import java.util.Arrays;
+import java.util.Optional;
+
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.scene.text.Font;
+import javafx.util.Callback;
+
+import org.controlsfx.control.PropertySheet;
+import org.controlsfx.control.PropertySheet.Item;
+
+/**
+ * A default implementation of the {@link Callback} type required by the
+ * {@link PropertySheet} 
+ * {@link PropertySheet#propertyEditorFactory() property editor factory}. By 
+ * default this is the implementation used by PropertySheet, but developers may
+ * choose to provide their own, or more likely, extend this implementation
+ * and override the {@link DefaultPropertyEditorFactory#call(org.controlsfx.control.PropertySheet.Item) } method to 
+ * add in support for additional editor types.
+ *
+ * @see PropertySheet
+ */
+public class DefaultPropertyEditorFactory implements Callback<Item, PropertyEditor<?>> {
+    
+    @Override public PropertyEditor<?> call(Item item) {
+        Class<?> type = item.getType();
+        
+        //TODO: add support for char and collection editors
+        
+        if (item.getPropertyEditorClass().isPresent()) {
+            Optional<PropertyEditor<?>> ed = Editors.createCustomEditor(item);
+            if (ed.isPresent()) return ed.get();
+        }
+        
+        if (/*type != null &&*/ type == String.class) {
+            return Editors.createTextEditor(item);  
+        }
+
+        if (/*type != null &&*/ isNumber(type)) {
+            return Editors.createNumericEditor(item);
+        }
+        
+        if (/*type != null &&*/(type == boolean.class || type == Boolean.class)) {
+            return Editors.createCheckEditor(item);
+        }
+
+        if (/*type != null &&*/type == LocalDate.class) {
+            return Editors.createDateEditor(item);
+        }
+        
+        if (/*type != null &&*/type == Color.class || type == Paint.class) {
+            return Editors.createColorEditor(item);
+        }
+
+        if (type != null && type.isEnum()) {
+            return Editors.createChoiceEditor(item, Arrays.<Object>asList(type.getEnumConstants()));
+        }
+        
+        if (/*type != null &&*/type == Font.class) {
+            return Editors.createFontEditor(item);
+        }
+        
+        return null; 
+    }
+    
+    private static Class<?>[] numericTypes = new Class[]{
+        byte.class, Byte.class,
+        short.class, Short.class,
+        int.class, Integer.class,
+        long.class, Long.class,
+        float.class, Float.class,
+        double.class, Double.class,
+        BigInteger.class, BigDecimal.class
+    };    
+    
+    // there should be better ways to do this
+    private static boolean isNumber(Class<?> type)  {
+        if ( type == null ) return false;
+        for (Class<?> cls : numericTypes) {
+            if ( type == cls ) return true;
+        }
+        return false;
+    }
+}
diff --git a/src/org/controlsfx/property/editor/Editors.java b/src/org/controlsfx/property/editor/Editors.java
new file mode 100644
index 0000000000000000000000000000000000000000..c742d49d597a9536a95969f33bcbd621d6424b25
--- /dev/null
+++ b/src/org/controlsfx/property/editor/Editors.java
@@ -0,0 +1,232 @@
+/**
+ * Copyright (c) 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.property.editor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.time.LocalDate;
+import java.util.Collection;
+import java.util.Optional;
+
+import javafx.application.Platform;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ColorPicker;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.DatePicker;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TextInputControl;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+
+import org.controlsfx.control.PropertySheet;
+import org.controlsfx.control.PropertySheet.Item;
+import org.controlsfx.dialog.FontSelectorDialog;
+
+@SuppressWarnings("deprecation")
+public class Editors {
+
+    private Editors() {
+        // no op
+    }
+    
+    public static final PropertyEditor<?> createTextEditor( Item property ) {
+    
+        return new AbstractPropertyEditor<String, TextField>(property, new TextField()) {
+
+            { enableAutoSelectAll(getEditor()); } 
+            
+            @Override protected StringProperty getObservableValue() {
+                return getEditor().textProperty();
+            }
+    
+            @Override public void setValue(String value) {
+                getEditor().setText(value);
+            }
+        };
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static final PropertyEditor<?> createNumericEditor( Item property ) {
+
+    	return new AbstractPropertyEditor<Number, NumericField>(property, new NumericField( (Class<? extends Number>) property.getType())) {
+
+			private Class<? extends Number> sourceClass = (Class<? extends Number>) property.getType(); //Double.class;
+            
+            { enableAutoSelectAll(getEditor()); }
+
+            @Override protected ObservableValue<Number> getObservableValue() {
+                return getEditor().valueProperty();
+            }
+
+            @Override public Number getValue() {
+                try {
+                    return sourceClass.getConstructor(String.class).newInstance(getEditor().getText());
+                } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
+                        | NoSuchMethodException | SecurityException e) {
+                    e.printStackTrace();
+                    return null;
+                }
+            }
+
+            @Override public void setValue(Number value) {
+                sourceClass = (Class<? extends Number>) value.getClass();
+                getEditor().setText(value.toString());
+            }
+            
+        };   
+    }
+    
+    public static final PropertyEditor<?> createCheckEditor( Item property ) {
+     
+        return new AbstractPropertyEditor<Boolean, CheckBox>(property, new CheckBox()) {
+
+            @Override protected BooleanProperty getObservableValue() {
+                return getEditor().selectedProperty();
+            }
+            
+            @Override public void setValue(Boolean value) {
+                getEditor().setSelected((Boolean)value);
+            }
+        };
+        
+    }
+    
+    public static final <T> PropertyEditor<?> createChoiceEditor( Item property, final Collection<T> choices ) {
+         
+        return new AbstractPropertyEditor<T, ComboBox<T>>(property, new ComboBox<T>()) {
+            
+            { getEditor().setItems(FXCollections.observableArrayList(choices)); }
+            
+            @Override protected ObservableValue<T> getObservableValue() {
+                return getEditor().getSelectionModel().selectedItemProperty();
+            }
+
+            @Override public void setValue(T value) {
+                getEditor().getSelectionModel().select(value);
+            }
+        };
+    }
+    
+    public static final PropertyEditor<?> createColorEditor( Item property ) {
+        return new AbstractPropertyEditor<Color, ColorPicker>(property, new ColorPicker()) {
+
+            @Override protected ObservableValue<Color> getObservableValue() {
+                return getEditor().valueProperty();
+            }
+
+            @Override public void setValue(Color value) {
+                getEditor().setValue((Color) value);
+            }
+        };
+    }
+    
+    
+    public static final PropertyEditor<?> createDateEditor( Item property ) {
+        return new AbstractPropertyEditor<LocalDate, DatePicker>(property, new DatePicker()) {
+            
+            //TODO: Provide date picker customization support
+            
+            @Override protected ObservableValue<LocalDate> getObservableValue() {
+                return getEditor().valueProperty();
+            }
+
+            @Override public void setValue(LocalDate value) {
+                getEditor().setValue((LocalDate) value);
+            }
+        };
+    }    
+    
+    public static final PropertyEditor<?> createFontEditor( Item property ) {
+        
+        return new AbstractPropertyEditor<Font, AbstractObjectField<Font>>(property, new AbstractObjectField<Font>() {
+                    @Override protected Class<Font> getType() {
+                        return Font.class;
+                    }
+                    
+                    @Override protected String objectToString(Font font) {
+                        return font == null? "": String.format("%s, %.1f", font.getName(), font.getSize()); //$NON-NLS-1$ //$NON-NLS-2$
+                    }
+        
+                    @Override protected Font edit(Font font) {
+                        FontSelectorDialog dlg = new FontSelectorDialog(font);
+                        Optional<Font> optionalFont = dlg.showAndWait();
+                        return optionalFont.get();
+                    }
+                }) {
+
+            @Override protected ObservableValue<Font> getObservableValue() {
+                return getEditor().getObjectProperty();
+            }
+
+            @Override public void setValue(Font value) {
+                getEditor().getObjectProperty().set(value);
+            }
+        };
+        
+    }
+    
+    /**
+     * Static method used to create an instance of the custom editor returned 
+     * via a call to {@link Item#getPropertyEditorClass() } 
+     * 
+     * The class returned must declare a constructor that takes a single 
+     * parameter of type PropertySheet.Item into which the parameter supplied 
+     * to this method will be passed.
+     * 
+     * @param property The {@link Item} that this editor will be 
+     * associated with.
+     * @return The {@link PropertyEditor} wrapped in an {@link Optional}
+     */
+    public static final Optional<PropertyEditor<?>> createCustomEditor(final Item property ) {
+        return property.getPropertyEditorClass().map(cls -> {
+            try {
+                Constructor<?> cn = cls.getConstructor(PropertySheet.Item.class);
+                if (cn != null) {
+                    return (PropertyEditor<?>) cn.newInstance(property);
+                }
+            } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+                ex.printStackTrace();
+            }
+            return null;
+        });
+    }
+    
+    private static void enableAutoSelectAll(final TextInputControl control) {
+        control.focusedProperty().addListener((ObservableValue<? extends Boolean> o, Boolean oldValue, Boolean newValue) -> {
+            if (newValue) {
+                Platform.runLater(() -> {
+                    control.selectAll();
+                });
+            }
+        });
+    }
+    
+}
diff --git a/src/org/controlsfx/property/editor/NumericField.java b/src/org/controlsfx/property/editor/NumericField.java
new file mode 100644
index 0000000000000000000000000000000000000000..c90f4131fb47f53154e1dd9c77fdad1b5d3f34e7
--- /dev/null
+++ b/src/org/controlsfx/property/editor/NumericField.java
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2015 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.property.editor;
+
+import java.math.BigInteger;
+
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.binding.NumberExpression;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleLongProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.IndexRange;
+import javafx.scene.control.TextField;
+
+/*
+ * TODO replace this with proper API when it becomes available:
+ * https://javafx-jira.kenai.com/browse/RT-30881
+ */
+class NumericField extends TextField {
+
+    private final NumericValidator<? extends Number> value ;
+    		
+    public NumericField( Class<? extends Number> cls ) {
+    	
+    	if ( cls == byte.class || cls == Byte.class || cls == short.class || cls == Short.class ||
+    		 cls ==	int.class  || cls == Integer.class || cls == long.class || cls == Long.class ||
+    	     cls == BigInteger.class) {
+    		value = new LongValidator(this);
+    	} else {
+    		value = new DoubleValidator(this);
+    	}
+    	
+        textProperty().addListener(new InvalidationListener() {
+            @Override public void invalidated(Observable arg0) {
+                value.setValue(value.toNumber(getText()));
+            }
+        });
+        
+    }
+    
+    public final ObservableValue<Number> valueProperty() {
+        return value;
+    }
+
+    @Override public void replaceText(int start, int end, String text) {
+        if (replaceValid(start, end, text)) {
+            super.replaceText(start, end, text);
+        }
+    }
+
+    @Override public void replaceSelection(String text) {
+        IndexRange range = getSelection();
+        if (replaceValid(range.getStart(), range.getEnd(), text)) {
+            super.replaceSelection(text);
+        }
+    }
+
+    private Boolean replaceValid(int start, int end, String fragment) {
+        try {
+        	String newText = getText().substring(0, start) + fragment + getText().substring(end);
+        	if (newText.isEmpty()) return true; 
+			value.toNumber(newText);
+        	return true;
+        } catch( Throwable ex ) {
+        	return false;
+        }
+    }
+    
+    
+    private static abstract interface NumericValidator<T extends Number> extends NumberExpression {
+    	void setValue(Number num);
+    	T toNumber(String s);
+    	
+    }
+    
+    static class DoubleValidator extends SimpleDoubleProperty implements NumericValidator<Double>{
+    	
+    	private NumericField field;
+    	
+    	public DoubleValidator(NumericField field) {
+    		super(field, "value", 0.0); //$NON-NLS-1$
+    		this.field = field;
+		}
+    	
+    	@Override protected void invalidated() {
+            field.setText(Double.toString(get()));
+        }
+
+		@Override
+		public Double toNumber(String s) {
+			if ( s == null || s.trim().isEmpty() ) return 0d;
+	    	String d = s.trim();
+	    	if ( d.endsWith("f") || d.endsWith("d") || d.endsWith("F") || d.endsWith("D") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+	    		throw new NumberFormatException("There should be no alpha symbols"); //$NON-NLS-1$
+	    	}
+	    	return new Double(d);
+		};
+		
+    }
+ 
+    
+    static class LongValidator extends SimpleLongProperty implements NumericValidator<Long>{
+    	
+    	private NumericField field;
+    	
+    	public LongValidator(NumericField field) {
+    		super(field, "value", 0l); //$NON-NLS-1$
+    		this.field = field;
+		}
+    	
+    	@Override protected void invalidated() {
+            field.setText(Long.toString(get()));
+        }
+
+		@Override
+		public Long toNumber(String s) {
+			if ( s == null || s.trim().isEmpty() ) return 0l;
+	    	String d = s.trim();
+	    	return new Long(d);
+		};
+		
+    }    
+    
+    
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/property/editor/PropertyEditor.java b/src/org/controlsfx/property/editor/PropertyEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..58dbf36c14933594a9fe4ca78a391a4aa62ce332
--- /dev/null
+++ b/src/org/controlsfx/property/editor/PropertyEditor.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.property.editor;
+
+import org.controlsfx.control.PropertySheet;
+
+import javafx.scene.Node;
+
+/**
+ * The base interface for all editors used by the {@link PropertySheet} control. 
+ *
+ * @param <T> The type of the property that the PropertyEditor is responsible
+ *      for editing.
+ */
+public interface PropertyEditor<T> {
+
+    /**
+     * Returns the editor responsible for editing this property.
+     */
+    public Node getEditor();
+
+    /**
+     * Returns the current value in the editor - this may not be the value of
+     * the property itself!
+     */
+    public T getValue();
+
+    /**
+     * Sets the value to display in the editor - this may not be the value of 
+     * the property itself - and the property value will not change!
+     */
+    public void setValue(T value);
+}
diff --git a/src/org/controlsfx/property/editor/package-info.java b/src/org/controlsfx/property/editor/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..67fd7dfe2d1c28b114fea46d707057786d3702cc
--- /dev/null
+++ b/src/org/controlsfx/property/editor/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * A package containing a number of useful editor classes related to the 
+ * {@link org.controlsfx.control.PropertySheet} control.
+ */
+package org.controlsfx.property.editor;
\ No newline at end of file
diff --git a/src/org/controlsfx/property/package-info.java b/src/org/controlsfx/property/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..366b5b56a40c39e8c55fee069609fa8684acd6f5
--- /dev/null
+++ b/src/org/controlsfx/property/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * A package containing a number of useful classes related to the 
+ * {@link org.controlsfx.control.PropertySheet} control.
+ */
+package org.controlsfx.property;
\ No newline at end of file
diff --git a/src/org/controlsfx/tools/Borders.java b/src/org/controlsfx/tools/Borders.java
new file mode 100644
index 0000000000000000000000000000000000000000..542c2f4dea56aad72c4b029e5465df0736710eff
--- /dev/null
+++ b/src/org/controlsfx/tools/Borders.java
@@ -0,0 +1,807 @@
+/**
+ * Copyright (c) 2013, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.tools;
+
+import javafx.geometry.Insets;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.layout.*;
+import javafx.scene.paint.Color;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A utility class that allows you to wrap JavaFX {@link Node Nodes} with a border,
+ * in a way somewhat analogous to the Swing {@link BorderFactory} (although with
+ * less options as a lot of what the Swing BorderFactory offers resulted in 
+ * ugly borders!).
+ * 
+ * <p>The Borders class provides a fluent API for specifying the properties of
+ * each border. It is possible to create multiple borders around a Node simply
+ * by continuing to call additional methods before you call the final 
+ * {@link Borders#build()} method. To use the Borders class, you simply call
+ * {@link Borders#wrap(Node)}, passing in the Node you wish to wrap the border(s)
+ * around. 
+ * 
+ * <h3>Examples</h3>
+ * <p>Firstly, lets wrap a JavaFX Button node with a simple line border that looks
+ * like the following:
+ * 
+ * <br>
+ * <center><img src="borders-lineBorder.png" alt="Screenshot of Borders.LineBorders"></center>
+ * 
+ * <p>Here's the code:</p>
+ * 
+ * <pre>
+ * {@code
+ * Button button = new Button("Hello World!");
+ * Node wrappedButton = Borders.wrap(button).lineBorder().buildAll();
+ * }</pre>
+ * 
+ * <p>Easy, isn't it!? You can make the border look a little nicer by replacing
+ * the line border with an {@link EtchedBorders etched border}. An etched border
+ * has a subtle inner (or outer) line that makes the border stand out a bit more,
+ * like this:
+ * 
+ * <br>
+ * <center><img src="borders-etchedBorder.png" alt="Screenshot of Borders.EtchedBorders"></center>
+ * 
+ * <p>Now that's one good looking border! Here's the code:</p>
+ * 
+ * <pre>
+ * {@code
+ * Button button = new Button("Hello World!");
+ * Node wrappedButton = Borders.wrap(button).etchedBorder().buildAll();
+ * }</pre>
+ * 
+ * <p>In some circumstances you want to have multiple borders. For example,
+ * you might two line borders. That's easy:
+ * 
+ * <br>
+ * <center><img src="borders-twoLines.png" alt="Screenshot of two Borders.LineBorders"></center>
+ * 
+ * <pre>
+ * {@code
+ * Node wrappedButton = Borders.wrap(button)
+ *     .lineBorder().color(Color.RED).build()
+ *     .lineBorder().color(Color.GREEN).build()
+ *     .build();
+ * }</pre>
+ * 
+ * <p>You simply chain the borders together, going from inside to outside!</p>
+ * 
+ * <p>Because of all the configuration options it isn't possible to list all the 
+ * functionality of all the border types, so refer to the rest of the javadocs 
+ * for inspiration.</p>
+ */
+public final class Borders {
+    
+    /**************************************************************************
+     * 
+     * Static fields
+     * 
+     **************************************************************************/
+    
+    private static final Color DEFAULT_BORDER_COLOR = Color.DARKGRAY;
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Internal fields
+     * 
+     **************************************************************************/
+    
+    private final Node node;
+    private final List<Border> borders;
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Fluent API entry method(s)
+     * 
+     **************************************************************************/
+    
+    public static Borders wrap(Node n) {
+        return new Borders(n);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Private Constructor
+     * 
+     **************************************************************************/
+    
+    private Borders(Node n) { 
+        this.node = n;
+        this.borders = new ArrayList<>();
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Fluent API
+     * 
+     **************************************************************************/
+    
+    /**
+     * Often times it is useful to have a bit of whitespace around a Node, to 
+     * separate it from what it is next to. Call this method to begin building
+     * a border that will wrap the node with a given amount of whitespace 
+     * (which can vary between the top, right, bottom, and left sides).
+     */
+    public EmptyBorders emptyBorder() {
+        return new EmptyBorders(this);
+    }
+    
+    /**
+     * The etched border look is essentially equivalent to the {@link #lineBorder()}
+     * look, except rather than one line, there are two. What is commonly done in
+     * this circumstance is that one of the lines is a very light colour (commonly
+     * white), which gives a nice etched look. Refer to the API in {@link EtchedBorders}
+     * for more information.
+     */
+    public EtchedBorders etchedBorder() {
+        return new EtchedBorders(this);
+    }
+    
+    /**
+     * Creates a nice, simple border around the node. Note that there are many
+     * configuration options in {@link LineBorders}, so explore it carefully.
+     */
+    public LineBorders lineBorder() {
+        return new LineBorders(this);
+    }
+    
+    /**
+     * Allows for developers to develop custom {@link Border} implementations,
+     * and to wrap them around a Node. Note that of course this is mostly 
+     * redundant (as you could just call {@link Border#wrap(Node)} directly).
+     * The only benefit is if you're creating a compound border consisting of 
+     * multiple borders, and you want your custom border included as part of 
+     * this.
+     */
+    public Borders addBorder(Border border) {
+        borders.add(border);
+        return this;
+    }
+
+    /**
+     * Returns the original node wrapped in zero or more borders, as specified
+     * using the fluent API.
+     */
+    public Node build() {
+        // we iterate through the borders list in reverse order
+        Node bundle = node;
+        for (int i = borders.size() - 1; i >= 0; i--) {
+            Border border = borders.get(i);
+            bundle = border.wrap(bundle);
+        }
+        return bundle;
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Support classes
+     * 
+     **************************************************************************/
+    
+    /**
+     * A fluent API that is only indirectly instantiable via the {@link Borders} 
+     * fluent API, and which allows for an {@link Borders#emptyBorder() empty border}
+     * to be wrapped around a given Node.
+     */
+    public class EmptyBorders {
+        private final Borders parent;
+        
+        private double top;
+        private double right;
+        private double bottom;
+        private double left;
+        
+        // private on purpose - this class is not directly instantiable.
+        private EmptyBorders(Borders parent) { 
+            this.parent = parent;
+        }
+        
+        /**
+         * Specifies that the wrapped Node should have the given padding around
+         * all four sides of itself.
+         */
+        public EmptyBorders padding(double padding) {
+            return padding(padding, padding, padding, padding);
+        }
+
+        /**
+         * Specifies that the wrapped Node should be wrapped with the given
+         * padding for each of its four sides, going in the order top, right,
+         * bottom, and finally left.
+         */
+        public EmptyBorders padding(double top, double right, double bottom, double left) {
+            this.top = top;
+            this.right = right;
+            this.bottom = bottom;
+            this.left = left;
+            return this;
+        }
+        
+        /**
+         * Builds the {@link Border} and {@link Borders#addBorder(Border) adds it}
+         * to the list of borders to wrap around the given Node (which will be
+         * constructed and returned when {@link Borders#build()} is called.
+         */
+        public Borders build() {
+            parent.addBorder(new StrokeBorder(null, buildStroke()));
+            return parent;
+        }
+        
+        /**
+         * A convenience method, this is equivalent to calling 
+         * {@link #build()} followed by {@link Borders#build()}. In other words,
+         * calling this will return the original Node wrapped in all its borders 
+         * specified.
+         */
+        public Node buildAll() {
+            build();
+            return parent.build();
+        }
+        
+        private BorderStroke buildStroke() {
+            return new BorderStroke(
+                null, 
+                BorderStrokeStyle.NONE,
+                null, 
+                new BorderWidths(top, right, bottom, left),
+                Insets.EMPTY);
+        }
+    }
+    
+    /**
+     * A fluent API that is only indirectly instantiable via the {@link Borders} 
+     * fluent API, and which allows for an {@link Borders#etchedBorder() etched border}
+     * to be wrapped around a given Node.
+     */
+    public class EtchedBorders {
+        private final Borders parent;
+        
+        private String title;
+        private boolean raised = false;
+        
+        private double outerTopPadding = 10;
+        private double outerRightPadding = 10;
+        private double outerBottomPadding = 10;
+        private double outerLeftPadding = 10;
+        
+        private double innerTopPadding = 15;
+        private double innerRightPadding = 15;
+        private double innerBottomPadding = 15;
+        private double innerLeftPadding = 15;
+        
+        private double topLeftRadius = 0;
+        private double topRightRadius = 0;
+        private double bottomRightRadius = 0;
+        private double bottomLeftRadius = 0;
+        
+        private Color highlightColor = DEFAULT_BORDER_COLOR;
+        private Color shadowColor = Color.WHITE;
+        
+        // private on purpose - this class is not directly instantiable.
+        private EtchedBorders(Borders parent) { 
+            this.parent = parent;
+        }
+        
+        /**
+         * Specifies the highlight colour to use in the etched border.
+         */
+        public EtchedBorders highlight(Color highlight) {
+            this.highlightColor = highlight;
+            return this;
+        }
+        
+        /**
+         * Specifies the shadow colour to use in the etched border.
+         */
+        public EtchedBorders shadow(Color shadow) {
+            this.shadowColor = shadow;
+            return this;
+        }
+        
+        /**
+         * Specifies the order in which the highlight and shadow colours are
+         * placed. A raised etched border has the shadow colour on the outside
+         * of the border, whereas a non-raised (or lowered) etched border has 
+         * the shadow colour on the inside of the border.
+         */
+        public EtchedBorders raised() {
+            raised = true;
+            return this;
+        }
+        
+        /**
+         * If desired, this specifies the title text to show in this border.
+         */
+        public EtchedBorders title(String title) {
+            this.title = title;
+            return this;
+        }
+        
+        /**
+         * Specifies the outer padding of the four lines of this border.
+         */
+        public EtchedBorders outerPadding(double padding) {
+            return outerPadding(padding, padding, padding, padding);
+        }
+        
+        /**
+         * Specifies that the line wrapping the node should have outer padding
+         * as specified, with each padding being independently configured, going 
+         * in the order top, right, bottom, and left.
+         */
+        public EtchedBorders outerPadding(double topPadding, double rightPadding, double bottomPadding, double leftPadding) {
+            this.outerTopPadding = topPadding;
+            this.outerRightPadding = rightPadding;
+            this.outerBottomPadding = bottomPadding;
+            this.outerLeftPadding = leftPadding;
+            
+            return this;
+        }
+        
+        /**
+         * Specifies the inner padding of the four lines of this border.
+         */
+        public EtchedBorders innerPadding(double padding) {
+            return innerPadding(padding, padding, padding, padding);
+        }
+        
+        /**
+         * Specifies that the line wrapping the node should have inner padding
+         * as specified, with each padding being independently configured, going 
+         * in the order top, right, bottom, and left.
+         */
+        public EtchedBorders innerPadding(double topPadding, double rightPadding, double bottomPadding, double leftPadding) {
+            this.innerTopPadding = topPadding;
+            this.innerRightPadding = rightPadding;
+            this.innerBottomPadding = bottomPadding;
+            this.innerLeftPadding = leftPadding;
+            
+            return this;
+        }
+        
+        /**
+         * Specifies the radius of the four corners of the lines of this border.
+         */
+        public EtchedBorders radius(double radius) {
+            return radius(radius, radius, radius, radius);
+        }
+        
+        /**
+         * Specifies that the etched line wrapping the node should have corner radii
+         * as specified, with each radius being independently configured, going 
+         * in the order top-left, top-right, bottom-right, and finally bottom-left.
+         */
+        public EtchedBorders radius(double topLeft, double topRight, double bottomRight, double bottomLeft) {
+            this.topLeftRadius = topLeft;
+            this.topRightRadius = topRight;
+            this.bottomRightRadius = bottomRight;
+            this.bottomLeftRadius = bottomLeft;
+            return this;
+        }
+        
+        /**
+         * Builds the {@link Border} and {@link Borders#addBorder(Border) adds it}
+         * to the list of borders to wrap around the given Node (which will be
+         * constructed and returned when {@link Borders#build()} is called.
+         */
+        public Borders build() {
+            Color inner = raised ? shadowColor : highlightColor;
+            Color outer = raised ? highlightColor : shadowColor;
+            BorderStroke innerStroke = new BorderStroke(
+                    inner, 
+                    BorderStrokeStyle.SOLID, 
+                    new CornerRadii(topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius, false), 
+                    new BorderWidths(1));
+            BorderStroke outerStroke = new BorderStroke(
+                    outer, 
+                    BorderStrokeStyle.SOLID, 
+                    new CornerRadii(topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius, false), 
+                    new BorderWidths(1), 
+                    new Insets(1));
+            
+            BorderStroke outerPadding = new EmptyBorders(parent)
+                .padding(outerTopPadding, outerRightPadding, outerBottomPadding, outerLeftPadding)
+                .buildStroke();
+            
+            BorderStroke innerPadding = new EmptyBorders(parent)
+                .padding(innerTopPadding, innerRightPadding, innerBottomPadding, innerLeftPadding)
+                .buildStroke();
+            
+            parent.addBorder(new StrokeBorder(null, outerPadding));
+            parent.addBorder(new StrokeBorder(title, innerStroke, outerStroke));
+            parent.addBorder(new StrokeBorder(null, innerPadding));
+            
+            return parent;
+        }
+        
+        /**
+         * A convenience method, this is equivalent to calling 
+         * {@link #build()} followed by {@link Borders#build()}. In other words,
+         * calling this will return the original Node wrapped in all its borders 
+         * specified.
+         */
+        public Node buildAll() {
+            build();
+            return parent.build();
+        }
+    }
+    
+    /**
+     * A fluent API that is only indirectly instantiable via the {@link Borders} 
+     * fluent API, and which allows for a {@link Borders#lineBorder() line border}
+     * to be wrapped around a given Node.
+     */
+    public class LineBorders {
+        private final Borders parent;
+        
+        private String title;
+        
+        private BorderStrokeStyle strokeStyle = BorderStrokeStyle.SOLID;
+        
+        private Color topColor = DEFAULT_BORDER_COLOR;
+        private Color rightColor = DEFAULT_BORDER_COLOR;
+        private Color bottomColor = DEFAULT_BORDER_COLOR;
+        private Color leftColor = DEFAULT_BORDER_COLOR;
+        
+        private double outerTopPadding = 10;
+        private double outerRightPadding = 10;
+        private double outerBottomPadding = 10;
+        private double outerLeftPadding = 10;
+        
+        private double innerTopPadding = 15;
+        private double innerRightPadding = 15;
+        private double innerBottomPadding = 15;
+        private double innerLeftPadding = 15;
+        
+        private double topThickness = 1;
+        private double rightThickness = 1;
+        private double bottomThickness = 1;
+        private double leftThickness = 1;
+
+        private double topLeftRadius = 0;
+        private double topRightRadius = 0;
+        private double bottomRightRadius = 0;
+        private double bottomLeftRadius = 0;
+        
+        // private on purpose - this class is not directly instantiable.
+        private LineBorders(Borders parent) { 
+            this.parent = parent;
+        }
+        
+        /**
+         * Specifies the colour to use for all four sides of this border.
+         */
+        public LineBorders color(Color color) {
+            return color(color, color, color, color);
+        }
+
+        /**
+         * Specifies that the wrapped Node should be wrapped with the given
+         * colours for each of its four sides, going in the order top, right,
+         * bottom, and finally left.
+         */
+        public LineBorders color(Color topColor, Color rightColor, Color bottomColor, Color leftColor) {
+            this.topColor = topColor;
+            this.rightColor = rightColor;
+            this.bottomColor = bottomColor;
+            this.leftColor = leftColor;
+            return this;
+        }
+        
+        /**
+         * Specifies which {@link BorderStrokeStyle} to use for this line border.
+         * By default this is {@link BorderStrokeStyle#SOLID}, but you can use
+         * any other style (such as {@link BorderStrokeStyle#DASHED}, 
+         * {@link BorderStrokeStyle#DOTTED}, or a custom style built using
+         * {@link BorderStrokeStyle#BorderStrokeStyle(javafx.scene.shape.StrokeType, javafx.scene.shape.StrokeLineJoin, javafx.scene.shape.StrokeLineCap, double, double, List)}.
+         */
+        public LineBorders strokeStyle(BorderStrokeStyle strokeStyle) {
+            this.strokeStyle = strokeStyle;
+            return this;
+        }
+        
+        /**
+         * Specifies the inner padding of the four lines of this border.
+         */
+        public LineBorders outerPadding(double padding) {
+            return outerPadding(padding, padding, padding, padding);
+        }
+        
+        /**
+         * Specifies that the line wrapping the node should have outer padding
+         * as specified, with each padding being independently configured, going 
+         * in the order top, right, bottom, and left.
+         */
+        public LineBorders outerPadding(double topPadding, double rightPadding, double bottomPadding, double leftPadding) {
+            this.outerTopPadding = topPadding;
+            this.outerRightPadding = rightPadding;
+            this.outerBottomPadding = bottomPadding;
+            this.outerLeftPadding = leftPadding;
+            
+            return this;
+        }
+        
+        /**
+         * Specifies the outer padding of the four lines of this border.
+         */
+        public LineBorders innerPadding(double padding) {
+            return innerPadding(padding, padding, padding, padding);
+        }
+        
+        /**
+         * Specifies that the line wrapping the node should have inner padding
+         * as specified, with each padding being independently configured, going 
+         * in the order top, right, bottom, and left.
+         */
+        public LineBorders innerPadding(double topPadding, double rightPadding, double bottomPadding, double leftPadding) {
+            this.innerTopPadding = topPadding;
+            this.innerRightPadding = rightPadding;
+            this.innerBottomPadding = bottomPadding;
+            this.innerLeftPadding = leftPadding;
+            
+            return this;
+        }
+        
+        /**
+         * Specifies the thickness of the line to use on all four sides of this
+         * border.
+         */
+        public LineBorders thickness(double thickness) {
+            return thickness(thickness, thickness, thickness, thickness);
+        }
+        
+        /**
+         * Specifies that the wrapped Node should be wrapped with the given
+         * line thickness for each of its four sides, going in the order top, right,
+         * bottom, and finally left.
+         */
+        public LineBorders thickness(double topThickness, double rightThickness, double bottomThickness, double leftThickness) {
+            this.topThickness = topThickness;
+            this.rightThickness = rightThickness;
+            this.bottomThickness = bottomThickness;
+            this.leftThickness = leftThickness;
+            return this;
+        }
+        
+        /**
+         * Specifies the radius of the four corners of the line of this border.
+         */
+        public LineBorders radius(double radius) {
+            return radius(radius, radius, radius, radius);
+        }
+        
+        /**
+         * Specifies that the line wrapping the node should have corner radii
+         * as specified, with each radius being independently configured, going 
+         * in the order top-left, top-right, bottom-right, and finally bottom-left.
+         */
+        public LineBorders radius(double topLeft, double topRight, double bottomRight, double bottomLeft) {
+            this.topLeftRadius = topLeft;
+            this.topRightRadius = topRight;
+            this.bottomRightRadius = bottomRight;
+            this.bottomLeftRadius = bottomLeft;
+            return this;
+        }
+        
+        /**
+         * If desired, this specifies the title text to show in this border.
+         */
+        public LineBorders title(String title) {
+            this.title = title;
+            return this;
+        }
+        
+        /**
+         * Builds the {@link Border} and {@link Borders#addBorder(Border) adds it}
+         * to the list of borders to wrap around the given Node (which will be
+         * constructed and returned when {@link Borders#build()} is called.
+         */
+        public Borders build() {
+            BorderStroke borderStroke = new BorderStroke(
+                    topColor, rightColor, bottomColor, leftColor, 
+                    strokeStyle, strokeStyle, strokeStyle, strokeStyle,  
+                    new CornerRadii(topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius, false), 
+                    new BorderWidths(topThickness, rightThickness, bottomThickness, leftThickness),
+                    null);
+            
+            BorderStroke outerPadding = new EmptyBorders(parent)
+                .padding(outerTopPadding, outerRightPadding, outerBottomPadding, outerLeftPadding)
+                .buildStroke();
+            
+            BorderStroke innerPadding = new EmptyBorders(parent)
+                .padding(innerTopPadding, innerRightPadding, innerBottomPadding, innerLeftPadding)
+                .buildStroke();
+            
+            parent.addBorder(new StrokeBorder(null, outerPadding));
+            parent.addBorder(new StrokeBorder(title, borderStroke));
+            parent.addBorder(new StrokeBorder(null, innerPadding));
+            
+            return parent;
+        }
+        
+        /**
+         * A convenience method, this is equivalent to calling 
+         * {@link #build()} followed by {@link Borders#build()}. In other words,
+         * calling this will return the original Node wrapped in all its borders 
+         * specified.
+         */
+        public Node buildAll() {
+            build();
+            return parent.build();
+        }
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Support interfaces
+     * 
+     **************************************************************************/
+    
+    /**
+     * The public interface used by the {@link Borders} API to wrap nodes with
+     * zero or more Border implementations. ControlsFX ships with a few 
+     * Border implementations (current {@link EmptyBorders}, {@link LineBorders},
+     * and {@link EtchedBorders}). As noted in {@link Borders#addBorder(Border)},
+     * this interface is relatively pointless, unless you plan to wrap a node
+     * with multiple borders and you want to use a custom {@link Border} 
+     * implementation for at least one border. In this case, you can simply 
+     * call {@link Borders#addBorder(Border)} with your custom border, when 
+     * appropriate.
+     */
+    @FunctionalInterface
+    public static interface Border {
+        
+        /**
+         * Given a {@link Node}, this method should return a Node that contains
+         * the original Node and also has wrapped it with an appropriate border.
+         */
+        public Node wrap(Node n);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Private support classes
+     * 
+     **************************************************************************/
+    
+    // --- Border implementations
+    private static class StrokeBorder implements Border {
+        private static final int TITLE_PADDING = 3;
+        private static final double GAP_PADDING = TITLE_PADDING * 2 - 1;
+        
+        private final String title;
+        private final BorderStroke[] borderStrokes;
+
+        public StrokeBorder(String title, BorderStroke... borderStrokes) {
+            this.title = title;
+            this.borderStrokes = borderStrokes;
+        }
+
+        @Override public Node wrap(final Node n) {
+            StackPane pane = new StackPane() {
+                Label titleLabel;
+                
+                {
+                    // add in the node we are wrapping
+                    getChildren().add(n);
+                    
+                    
+                    // if the title string is set, then also add in the title label
+                    if (title != null) {
+                        titleLabel = new Label(title);
+    
+                        // give the text a bit of space on the left...
+                        titleLabel.setPadding(new Insets(0, 0, 0, TITLE_PADDING));
+                        getChildren().add(titleLabel);
+                    }
+                }
+
+                @Override protected void layoutChildren() {
+                    super.layoutChildren();
+
+                    if (titleLabel != null) {
+                        // layout the title label
+                        final double labelHeight = titleLabel.prefHeight(-1);
+                        final double labelWidth = titleLabel.prefWidth(labelHeight) + TITLE_PADDING;
+                        titleLabel.resize(labelWidth, labelHeight);
+                        titleLabel.relocate(TITLE_PADDING * 2, -labelHeight / 2.0 - 1);
+
+                        List<BorderStroke> newBorderStrokes = new ArrayList<>(2);
+
+                        // create a line gap for the title label
+                        for (BorderStroke bs : borderStrokes) {
+                            List<Double> dashList = new ArrayList<>();
+
+                            // Create a dash list for the line gap or add it at the beginning of an existing dash list. This gap should be wide enough for the title label.
+                            if (bs.getTopStyle().getDashArray().isEmpty())
+                                dashList.addAll(Arrays.asList(GAP_PADDING, labelWidth, Double.MAX_VALUE));
+                            else { // dash pattern exists
+                                // insert gap in existing dash pattern and multiply original pattern so that gap does not show more then once
+                                double origDashWidth = bs.getTopStyle().getDashArray().stream().mapToDouble(d -> d).sum();
+
+                                if (origDashWidth > GAP_PADDING) {
+                                    dashList.add(GAP_PADDING);
+                                    dashList.add(labelWidth);
+                                } else { // need to insert dash pattern before the gap
+                                    int no = (int) (GAP_PADDING / origDashWidth);
+
+                                    for (int i = 0; i < no; i++)
+                                        dashList.addAll(bs.getTopStyle().getDashArray());
+
+                                    if ((dashList.size() & 1) == 0) // if size is even number, add one more element because gap must be at odd index to be transparent
+                                        dashList.add(0d);
+
+                                    dashList.add(labelWidth + GAP_PADDING - no * origDashWidth);
+                                }
+
+                                for (int i = 0; i < (getWidth() - labelWidth - origDashWidth) / origDashWidth; i++)
+                                    dashList.addAll(bs.getTopStyle().getDashArray());
+                            }
+
+                            // create new border stroke style for the top border line with new dash list
+                            BorderStrokeStyle topStrokeStyle = new BorderStrokeStyle(
+                                bs.getTopStyle().getType(), bs.getTopStyle().getLineJoin(), bs.getTopStyle().getLineCap(),
+                                bs.getTopStyle().getMiterLimit(), bs.getTopStyle().getDashOffset(), dashList);
+
+                            // change existing border stroke to utilize new top border line stroke style
+                            newBorderStrokes.add(new BorderStroke(
+                                bs.getTopStroke(), bs.getRightStroke(), bs.getBottomStroke(), bs.getLeftStroke(),
+                                topStrokeStyle, bs.getRightStyle(), bs.getBottomStyle(), bs.getLeftStyle(),
+                                bs.getRadii(), bs.getWidths(), null));
+                        }
+
+                        setBorder(new javafx.scene.layout.Border(newBorderStrokes.toArray(new BorderStroke[newBorderStrokes.size()])));
+                    }
+                }
+            };
+
+            pane.setBorder(new javafx.scene.layout.Border(borderStrokes));
+            return pane;
+        }
+    }
+}
diff --git a/src/org/controlsfx/tools/Duplicatable.java b/src/org/controlsfx/tools/Duplicatable.java
new file mode 100644
index 0000000000000000000000000000000000000000..1fd50fd4456cc978ba2e5c78c9b84583fc0ecab5
--- /dev/null
+++ b/src/org/controlsfx/tools/Duplicatable.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.tools;
+
+import javafx.scene.Node;
+
+/**
+ * An interface used in ControlsFX to represent something that can be duplicated,
+ * as in the JavaFX scenegraph it is not possible to insert the same 
+ * {@link Node} in multiple locations at the same time. Therefore, to work 
+ * around this the node may implement this interface to duplicate itself.
+ *
+ * @param <T> The node type
+ */
+@FunctionalInterface
+public interface Duplicatable<T> {
+   T duplicate();
+}
diff --git a/src/org/controlsfx/tools/Platform.java b/src/org/controlsfx/tools/Platform.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a0eae765cfd0fe2580ed27c6e713fe91702b30f
--- /dev/null
+++ b/src/org/controlsfx/tools/Platform.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.tools;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Represents operating system with appropriate properties 
+ *
+ */
+public enum Platform {
+    
+    WINDOWS("windows"), //$NON-NLS-1$
+    OSX("mac"), //$NON-NLS-1$
+    UNIX("unix"), //$NON-NLS-1$
+    UNKNOWN(""); //$NON-NLS-1$
+    
+    private static Platform current = getCurrentPlatform();
+    
+    private String platformId;
+    
+    Platform( String platformId ) {
+        this.platformId = platformId;
+    }
+    
+    /**
+     * Returns platform id. Usually used to specify platform dependent styles
+     * @return platform id
+     */
+    public String getPlatformId() {
+        return platformId;
+    }
+    
+    /**
+     * @return the current OS.
+     */
+    public static Platform getCurrent() {
+        return current;
+    }
+    
+    private static Platform getCurrentPlatform() {
+        String osName = System.getProperty("os.name");
+        if ( osName.startsWith("Windows") ) return WINDOWS;        
+        if ( osName.startsWith("Mac") )     return OSX;
+        if ( osName.startsWith("SunOS") )   return UNIX;
+        if ( osName.startsWith("Linux") ) {
+            String javafxPlatform = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                @Override
+                public String run() {
+                    return System.getProperty("javafx.platform");
+                }
+            });
+            if (! ( "android".equals(javafxPlatform) || "Dalvik".equals(System.getProperty("java.vm.name")) ) ) // if not Android
+                return UNIX;
+        }
+        return UNKNOWN;
+    }
+    
+}
diff --git a/src/org/controlsfx/tools/SVGLoader.java b/src/org/controlsfx/tools/SVGLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..c25ecb106dbf8121f1e8f9d32281ce89d7338f25
--- /dev/null
+++ b/src/org/controlsfx/tools/SVGLoader.java
@@ -0,0 +1,227 @@
+/**
+ * Copyright (c) 2013, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.tools;
+
+import java.net.URL;
+
+import javafx.beans.value.ChangeListener;
+import javafx.concurrent.Worker.State;
+import javafx.geometry.Rectangle2D;
+import javafx.scene.Scene;
+import javafx.scene.SnapshotParameters;
+import javafx.scene.SnapshotResult;
+import javafx.scene.image.ImageView;
+import javafx.scene.image.WritableImage;
+import javafx.scene.paint.Color;
+import javafx.scene.web.WebEngine;
+import javafx.scene.web.WebView;
+import javafx.stage.Stage;
+import javafx.util.Callback;
+
+import com.sun.javafx.webkit.Accessor;
+import com.sun.webkit.WebPage;
+
+/**
+ * Convenience class that will attempt to load a given URL as an .svg file.
+ */
+class SVGLoader {
+    
+    private SVGLoader() {
+        // no-op
+    }
+
+    /**
+     * This method will attempt to load the given svgImage URL into an ImageView
+     * node that will be provided asynchronously via the provided 
+     * {@link Callback}, and it will be sized to the given prefWidth / prefHeight.
+     * 
+     * <p>Note that it is valid to pass in -1 to prefWidth and / or prefHeight as
+     * an indicator to the SVG loader. If both values are -1, the default width
+     * of the SVG will be used. If one of the values is -1, then the SVG will
+     * be sized to ensure that it remains proportional.
+     * 
+     * @param svgImage The image to load.
+     * @param prefWidth The preferred width of the image when loaded, or -1 if 
+     *      there is no preferred width.
+     * @param prefHeight The preferred height of the image when loaded, or -1 if 
+     *      there is no preferred height.
+     * @param callback The {@link Callback} that will be called when the SVG 
+     *      image is loaded, where the {@link ImageView} containing the rendered
+     *      image will be available.
+     */
+    public static void loadSVGImage(final URL svgImage, 
+                                    final double prefWidth, 
+                                    final double prefHeight, 
+                                    final Callback<ImageView, Void> callback) {
+        loadSVGImage(svgImage, prefWidth, prefHeight, callback, null);
+    }
+    
+    /**
+     * This method will attempt to load the given svgImage URL into the provided
+     * {@link WritableImage}, with the SVG scaled to fit the size of the
+     * WritableImage.
+     * 
+     * @param svgImage The image to load.
+     * @param outputImage The location to write the loaded image once it has 
+     *      been rendered (it will not happen synchronously).
+     * @throws NullPointerException The outputImage argument must be non-null.
+     */
+    public static void loadSVGImage(final URL svgImage, 
+                                    final WritableImage outputImage) {
+        if (outputImage == null) {
+            throw new NullPointerException("outputImage can not be null"); //$NON-NLS-1$
+        }
+        final double w = outputImage.getWidth();
+        final double h = outputImage.getHeight();
+        loadSVGImage(svgImage, w, h, null, outputImage);
+    }
+    
+    public static void loadSVGImage(final URL svgImage, 
+                                    final double prefWidth, 
+                                    final double prefHeight, 
+                                    final Callback<ImageView, Void> callback, 
+                                    final WritableImage outputImage) {
+        final WebView view = new WebView();
+        final WebEngine eng = view.getEngine();
+        
+        // using non-public API to ensure background transparency
+        final WebPage webPage = Accessor.getPageFor(eng);
+        webPage.setBackgroundColor(webPage.getMainFrame(), 0xffffff00);
+        webPage.setOpaque(webPage.getMainFrame(), false); 
+        // end of non-public API
+
+        // temporary scene / stage
+        final Scene scene = new Scene(view);
+        final Stage stage = new Stage();
+        stage.setScene(scene);
+        stage.setWidth(0);
+        stage.setHeight(0);
+        stage.setOpacity(0);
+        stage.show();
+        
+//        String svgString = readFile(svgImage);
+
+        String content =
+        "<html>" + //$NON-NLS-1$
+            "<body style=\"margin-top: 0px; margin-bottom: 30px; margin-left: 0px; margin-right: 0px; padding: 0;\">" + //$NON-NLS-1$
+//                "<div style=\"width: " + prefWidth + "; height: " + prefHeight + ";\">" +
+                    "<img id=\"svgImage\" style=\"display: block;float: top;\" width=\"" + prefWidth + "\" height=\"" + prefHeight + "\" src=\"" + svgImage.toExternalForm() + "\" />" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+//                    svgString +
+//                "</div>" +
+            "</body>" + //$NON-NLS-1$
+        "</head>"; //$NON-NLS-1$
+                
+        
+        
+        eng.loadContent(content);
+        
+        eng.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
+            @Override public void changed(javafx.beans.value.ObservableValue<? extends State> o, State oldValue, State newValue) {
+                if (newValue == State.SUCCEEDED) {
+                    
+//                    HTMLImageElement svgImageElement = (HTMLImageElement) getSvgDom(eng);
+//                    System.out.println(svgImageElement.getAttributes());
+                    
+                    final double svgWidth = prefWidth >= 0 ? prefWidth : getSvgWidth(eng);
+                    final double svgHeight = prefHeight >= 0 ? prefWidth : getSvgHeight(eng);
+                    
+                    SnapshotParameters params = new SnapshotParameters();
+                    params.setFill(Color.TRANSPARENT);
+                    params.setViewport(new Rectangle2D(0, 0, svgWidth, svgHeight));
+                    
+                    view.snapshot(new Callback<SnapshotResult, Void>() {
+                        @Override public Void call(SnapshotResult param) {
+                            WritableImage snapshot = param.getImage();
+                            ImageView image = new ImageView(snapshot);
+                            
+                            if (callback != null) {
+                                callback.call(image);
+                            }
+                            
+                            stage.hide();
+                            return null;
+                        }
+                    }, params, outputImage);
+                }
+            }
+        });
+    }
+    
+//    private static String readFile(URL url) {
+//        try {
+//            FileInputStream stream = new FileInputStream(new File(url.toURI()));
+//            try {
+//                FileChannel fc = stream.getChannel();
+//                MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+//                return Charset.defaultCharset().decode(bb).toString();
+//            }
+//            finally {
+//                stream.close();
+//            }
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//        return null;
+//    }
+    
+    private static double getSvgWidth(WebEngine webEngine) {
+        Object result = getSvgDomProperty(webEngine, "offsetWidth"); //$NON-NLS-1$
+        if (result instanceof Integer) {
+            return (Integer) result;
+        }
+        return -1;
+    }
+    
+    private static double getSvgHeight(WebEngine webEngine) {
+        Object result = getSvgDomProperty(webEngine, "offsetHeight"); //$NON-NLS-1$
+        if (result instanceof Integer) {
+            return (Integer) result;
+        }
+        return -1;
+    }
+    
+    private static Object getSvgDomProperty(final WebEngine webEngine, final String property) {
+        return webEngine.executeScript("document.getElementById('svgImage')." + property); //$NON-NLS-1$
+    }
+
+//    private static HTMLImageElement getSvgDom(WebEngine webEngine) {
+//        return (HTMLImageElement) webEngine.executeScript("document.getElementById('svgImage')");
+//    }
+//    
+//    private static void printDocument(Document doc, OutputStream out) throws IOException, TransformerException {
+//        TransformerFactory tf = TransformerFactory.newInstance();
+//        Transformer transformer = tf.newTransformer();
+//        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
+//        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+//        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+//        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+//        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+//
+//        transformer.transform(new DOMSource(doc), 
+//             new StreamResult(new OutputStreamWriter(out, "UTF-8")));
+//    }
+}
diff --git a/src/org/controlsfx/tools/Utils.java b/src/org/controlsfx/tools/Utils.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7b236d82be055d3bc1e8ad2f3a30f05d4677414
--- /dev/null
+++ b/src/org/controlsfx/tools/Utils.java
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.tools;
+
+import java.util.Iterator;
+
+import javafx.scene.Node;
+import javafx.stage.PopupWindow;
+import javafx.stage.Window;
+
+public class Utils {
+
+    /**
+     * Will return a {@link Window} from an object if any can be found. {@code null}
+     * value can be given, the program will then try to find the focused window
+     * among those available.
+     * 
+     * @param owner the object whose window is to be found.
+     * @return the window of the given object.
+     */
+    public static Window getWindow(Object owner) throws IllegalArgumentException {
+        if (owner == null) {
+            Window window = null;
+            // lets just get the focused stage and show the dialog in there
+            @SuppressWarnings("deprecation")
+            Iterator<Window> windows = Window.impl_getWindows();
+            while (windows.hasNext()) {
+                window = windows.next();
+                if (window.isFocused() && !(window instanceof PopupWindow)) {
+                    break;
+                }
+            }
+            return window;
+        } else if (owner instanceof Window) {
+            return (Window) owner;
+        } else if (owner instanceof Node) {
+            return ((Node) owner).getScene().getWindow();
+        } else {
+            throw new IllegalArgumentException("Unknown owner: " + owner.getClass()); //$NON-NLS-1$
+        }
+    }
+    
+    /**
+     * Return a letter (just like Excel) associated with the number. When the
+     * number is under 26, a simple letter is returned. When the number is
+     * superior, concatenated letters are returned.
+     * 
+     * 
+     * For example: 0 -&gt; A 1 -&gt; B 26 -&gt; AA 32 -&gt; AG 45 -&gt; AT
+     * 
+     * 
+     * @param number the number whose Excel Letter is to be found.
+     * @return a letter (like) associated with the number.
+     */
+    public static final String getExcelLetterFromNumber(int number) {
+        String letter = ""; //$NON-NLS-1$
+        // Repeatedly divide the number by 26 and convert the
+        // remainder into the appropriate letter.
+        while (number >= 0) {
+            final int remainder = number % 26;
+            letter = (char) (remainder + 'A') + letter;
+            number = number / 26 - 1;
+        }
+
+        return letter;
+    }
+	
+    /**
+     * Simple utility function which clamps the given value to be strictly
+     * between the min and max values.
+     */
+    public static double clamp(double min, double value, double max) {
+        if (value < min) return min;
+        if (value > max) return max;
+        return value;
+    }
+
+    /**
+     * Utility function which returns either {@code less} or {@code more}
+     * depending on which {@code value} is closer to. If {@code value}
+     * is perfectly between them, then either may be returned.
+     */
+    public static double nearest(double less, double value, double more) {
+        double lessDiff = value - less;
+        double moreDiff = more - value;
+        if (lessDiff < moreDiff) return less;
+        return more;
+    }
+}
diff --git a/src/org/controlsfx/tools/ValueExtractor.java b/src/org/controlsfx/tools/ValueExtractor.java
new file mode 100644
index 0000000000000000000000000000000000000000..b64b4ed67df7226a91e70b97a4844c3d5e642535
--- /dev/null
+++ b/src/org/controlsfx/tools/ValueExtractor.java
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) 2014 ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.tools;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.scene.Node;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ChoiceBox;
+import javafx.scene.control.ColorPicker;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Control;
+import javafx.scene.control.DatePicker;
+import javafx.scene.control.ListView;
+import javafx.scene.control.MultipleSelectionModel;
+import javafx.scene.control.RadioButton;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.Slider;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TextInputControl;
+import javafx.scene.control.TreeTableView;
+import javafx.scene.control.TreeView;
+import javafx.util.Callback;
+
+public class ValueExtractor {
+	
+	private static class ObservableValueExtractor {
+
+        public final Predicate<Control> applicability;
+		public final Callback<Control, ObservableValue<?>> extraction;
+
+        public ObservableValueExtractor( Predicate<Control> applicability, Callback<Control, ObservableValue<?>> extraction ) {
+            this.applicability = Objects.requireNonNull(applicability);
+            this.extraction    = Objects.requireNonNull(extraction);
+        }
+
+    }
+
+    private static List<ObservableValueExtractor> extractors = FXCollections.observableArrayList(); 
+
+    /**
+     * Add "obervable value extractor" for custom controls.
+     * @param test applicability test
+     * @param extract extraction of observable value
+     */
+    public static void addObservableValueExtractor( Predicate<Control> test, Callback<Control, ObservableValue<?>> extract ) {
+        extractors.add( new ObservableValueExtractor(test, extract));
+    }
+
+    static {
+        addObservableValueExtractor( c -> c instanceof TextInputControl, c -> ((TextInputControl)c).textProperty());
+        addObservableValueExtractor( c -> c instanceof ComboBox,         c -> ((ComboBox<?>)c).valueProperty());
+        addObservableValueExtractor( c -> c instanceof ChoiceBox,        c -> ((ChoiceBox<?>)c).valueProperty());
+        addObservableValueExtractor( c -> c instanceof CheckBox,         c -> ((CheckBox)c).selectedProperty());
+        addObservableValueExtractor( c -> c instanceof Slider,           c -> ((Slider)c).valueProperty());
+        addObservableValueExtractor( c -> c instanceof ColorPicker,      c -> ((ColorPicker)c).valueProperty());
+        addObservableValueExtractor( c -> c instanceof DatePicker,       c -> ((DatePicker)c).valueProperty());
+
+        addObservableValueExtractor( c -> c instanceof ListView,         c -> ((ListView<?>)c).itemsProperty());
+        addObservableValueExtractor( c -> c instanceof TableView,        c -> ((TableView<?>)c).itemsProperty());
+
+        // FIXME: How to listen for TreeView changes???
+        //addObservableValueExtractor( c -> c instanceof TreeView,         c -> ((TreeView<?>)c).Property());
+    }
+	
+	
+	
+    public static final Optional<Callback<Control, ObservableValue<?>>> getObservableValueExtractor(final Control c) {
+        for( ObservableValueExtractor e: extractors ) {
+            if ( e.applicability.test(c)) return Optional.of(e.extraction);
+        }
+        return Optional.empty();
+    }
+    
+    
+    private static class NodeValueExtractor {
+
+        public final Predicate<Node> applicability;
+		public final Callback<Node, Object> extraction;
+
+        public NodeValueExtractor( Predicate<Node> applicability, Callback<Node, Object> extraction ) {
+            this.applicability = Objects.requireNonNull(applicability);
+            this.extraction    = Objects.requireNonNull(extraction);
+        }
+
+    }
+    
+
+    private static final List<NodeValueExtractor> valueExtractors = FXCollections.observableArrayList();
+    
+    static {
+        addValueExtractor( n -> n instanceof CheckBox,         cb -> ((CheckBox)cb).isSelected());
+        addValueExtractor( n -> n instanceof ChoiceBox,        cb -> ((ChoiceBox<?>)cb).getValue());
+        addValueExtractor( n -> n instanceof ComboBox,         cb -> ((ComboBox<?>)cb).getValue());
+        addValueExtractor( n -> n instanceof DatePicker,       dp -> ((DatePicker)dp).getValue());
+        addValueExtractor( n -> n instanceof RadioButton,      rb -> ((RadioButton)rb).isSelected());
+        addValueExtractor( n -> n instanceof Slider,           sl -> ((Slider)sl).getValue());
+        addValueExtractor( n -> n instanceof TextInputControl, ta -> ((TextInputControl)ta).getText());
+        
+        addValueExtractor( n -> n instanceof ListView, lv -> {
+            MultipleSelectionModel<?> sm = ((ListView<?>)lv).getSelectionModel();
+            return sm.getSelectionMode() == SelectionMode.MULTIPLE ? sm.getSelectedItems() : sm.getSelectedItem();
+        });
+        addValueExtractor( n -> n instanceof TreeView, tv -> {
+            MultipleSelectionModel<?> sm = ((TreeView<?>)tv).getSelectionModel();
+            return sm.getSelectionMode() == SelectionMode.MULTIPLE ? sm.getSelectedItems() : sm.getSelectedItem();
+        });
+        addValueExtractor( n -> n instanceof TableView, tv -> {
+            MultipleSelectionModel<?> sm = ((TableView<?>)tv).getSelectionModel();
+            return sm.getSelectionMode() == SelectionMode.MULTIPLE ? sm.getSelectedItems() : sm.getSelectedItem();
+        });
+        addValueExtractor( n -> n instanceof TreeTableView, tv -> {
+            MultipleSelectionModel<?> sm = ((TreeTableView<?>)tv).getSelectionModel();
+            return sm.getSelectionMode() == SelectionMode.MULTIPLE ? sm.getSelectedItems() : sm.getSelectedItem();
+        });
+    }
+    
+    private ValueExtractor() {
+        // no-op
+    }
+    
+    public static void addValueExtractor(Predicate<Node> test, Callback<Node, Object> extractor) {
+        valueExtractors.add(new NodeValueExtractor(test, extractor));
+    }
+    
+    /**
+     * Attempts to return a value for the given Node. This is done by checking
+     * the map of value extractors, contained within this class. This
+     * map contains value extractors for common UI controls, but more extractors
+     * can be added by calling {@link #addObservableValueExtractor(Predicate, Callback)}.
+     * 
+     * @param n The node from whom a value will hopefully be extracted.
+     * @return The value of the given node.
+     */
+    public static Object getValue(Node n) {
+    	for( NodeValueExtractor nve: valueExtractors ) {
+            if ( nve.applicability.test(n)) return nve.extraction.call(n);
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/src/org/controlsfx/tools/package-info.java b/src/org/controlsfx/tools/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..af1fe9a0158b812716080343b22484b39df3cbcf
--- /dev/null
+++ b/src/org/controlsfx/tools/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * A package containing a number of useful utility methods.
+ */
+package org.controlsfx.tools;
\ No newline at end of file
diff --git a/src/org/controlsfx/validation/Severity.java b/src/org/controlsfx/validation/Severity.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab51e3e7b4789cb2ba7f18d4c5af7af8f7198bfa
--- /dev/null
+++ b/src/org/controlsfx/validation/Severity.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation;
+
+/**
+ * Defines severity of validation messages 
+ */
+public enum Severity {
+
+    ERROR,
+    WARNING
+
+}
diff --git a/src/org/controlsfx/validation/SimpleValidationMessage.java b/src/org/controlsfx/validation/SimpleValidationMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..314d67b9d52085a7cb47427e58a6613dec2ea3b3
--- /dev/null
+++ b/src/org/controlsfx/validation/SimpleValidationMessage.java
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation;
+
+import javafx.scene.control.Control;
+
+/**
+ * Internal implementation of simple validation message 
+ */
+class SimpleValidationMessage implements ValidationMessage {
+
+    private final String text;
+    private final Severity severity;
+    private final Control target;
+
+    public SimpleValidationMessage( Control target, String text, Severity severity ) {
+        this.text = text;
+        this.severity = severity == null? Severity.ERROR: severity;
+        this.target = target;
+    }
+
+    @Override public Control getTarget() {
+        return target;
+    }
+
+    @Override public String getText() {
+        return text;
+    }
+
+    @Override public Severity getSeverity() {
+        return severity;
+    }
+
+    @Override public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result
+                + ((severity == null) ? 0 : severity.hashCode());
+        result = prime * result + ((target == null) ? 0 : target.hashCode());
+        result = prime * result + ((text == null) ? 0 : text.hashCode());
+        return result;
+    }
+
+    @Override public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        SimpleValidationMessage other = (SimpleValidationMessage) obj;
+        if (severity != other.severity)
+            return false;
+        if (target == null) {
+            if (other.target != null)
+                return false;
+        } else if (!target.equals(other.target))
+            return false;
+        if (text == null) {
+            if (other.text != null)
+                return false;
+        } else if (!text.equals(other.text))
+            return false;
+        return true;
+    }
+
+    @Override public String toString() {
+        return String.format("%s(%s)", severity, text); //$NON-NLS-1$
+    }
+
+}
diff --git a/src/org/controlsfx/validation/ValidationMessage.java b/src/org/controlsfx/validation/ValidationMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..4b836d6dbcc402328498b2edc18f66b5a31c375c
--- /dev/null
+++ b/src/org/controlsfx/validation/ValidationMessage.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation;
+
+import java.util.Comparator;
+
+import javafx.scene.control.Control;
+
+/**
+ * Interface to define basic contract for validation message  
+ */
+public interface ValidationMessage extends Comparable<ValidationMessage>{
+
+	public static final Comparator<ValidationMessage> COMPARATOR = new Comparator<ValidationMessage>() {
+
+		@Override
+		public int compare(ValidationMessage vm1, ValidationMessage vm2) {
+			if ( vm1 == vm2 ) return  0;
+			if ( vm1 == null) return  1;
+			if ( vm2 == null) return -1;
+			return vm1.compareTo(vm2);
+		}
+	};
+	
+    /**
+     * Message text
+     * @return message text
+     */
+    public String getText();
+
+    /**
+     * Message {@link Severity} 
+     * @return message severity
+     */
+    public Severity getSeverity();
+
+
+    /**
+     * Message target - {@link Control} which message is related to . 
+     * @return message target
+     */
+    public Control getTarget();
+
+    /**
+     * Factory method to create a simple error message 
+     * @param target message target
+     * @param text message text 
+     * @return error message
+     */
+    public static ValidationMessage error( Control target, String text ) {
+        return new SimpleValidationMessage(target, text, Severity.ERROR);
+    }
+
+    /**
+     * Factory method to create a simple warning message 
+     * @param target message target
+     * @param text message text 
+     * @return warning message
+     */
+    public static ValidationMessage warning( Control target, String text ) {
+        return new SimpleValidationMessage(target, text, Severity.WARNING);
+    }
+
+    @Override default public int compareTo(ValidationMessage msg) {
+        return msg == null || getTarget() != msg.getTarget() ? -1: getSeverity().compareTo(msg.getSeverity());
+    }
+}
diff --git a/src/org/controlsfx/validation/ValidationResult.java b/src/org/controlsfx/validation/ValidationResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..460bb3f98cdcce7051066cdf0649fc491868dda5
--- /dev/null
+++ b/src/org/controlsfx/validation/ValidationResult.java
@@ -0,0 +1,276 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javafx.scene.control.Control;
+
+/**
+ * Validation result. Can generally be thought of a collection of validation messages.
+ * Allows for quick an painless accumulation of the messages. 
+ * Also provides ability to combine validation results 
+ */
+public class ValidationResult {
+
+    private List<ValidationMessage> errors   = new ArrayList<>();
+    private List<ValidationMessage> warnings = new ArrayList<>();
+
+    /**
+     * Creates empty validation result
+     */
+    public ValidationResult() {}
+
+    /**
+     * Factory method to create validation result out of one message
+     * @param target validation target 
+     * @param text message text 
+     * @param severity message severity
+     * @param condition condition on which message will be added to validation result
+     * @return New instance of validation result
+     */
+    public static final ValidationResult fromMessageIf( Control target, String text, Severity severity, boolean condition ) {
+        return new ValidationResult().addMessageIf(target, text, severity, condition);
+    }
+
+    /**
+     * Factory method to create validation result out of one error
+     * @param target validation target 
+     * @param text message text 
+     * @param condition condition on which message will be added to validation result
+     * @return New instance of validation result
+     */
+    public static final ValidationResult fromErrorIf( Control target, String text, boolean condition ) {
+        return new ValidationResult().addErrorIf(target, text, condition);
+    }
+
+    /**
+     * Factory method to create validation result out of one warning
+     * @param target validation target 
+     * @param text message text 
+     * @param condition condition on which message will be added to validation result
+     * @return New instance of validation result
+     */
+    public static final ValidationResult fromWarningIf( Control target, String text, boolean condition ) {
+        return new ValidationResult().addWarningIf(target, text, condition);
+    }
+
+    /**
+     * Factory method to create validation result out of one error
+     * @param target validation target 
+     * @param text message text 
+     * @return New instance of validation result
+     */
+    public static final ValidationResult fromError( Control target, String text ) {
+        return fromMessages( ValidationMessage.error(target, text));
+    }
+
+    /**
+     * Factory method to create validation result out of one warning
+     * @param target validation target 
+     * @param text message text 
+     * @return New instance of validation result
+     */
+    public static final ValidationResult fromWarning( Control target, String text ) {
+        return fromMessages( ValidationMessage.warning(target, text));
+    }
+
+    /**
+     * Factory method to create validation result out of several messages
+     * @param messages
+     * @return New instance of validation result
+     */
+    public static final ValidationResult fromMessages( ValidationMessage... messages ) {
+        return new ValidationResult().addAll(messages);
+    }
+
+    /**
+     * Factory method to create validation result out of collection of messages
+     * @param messages
+     * @return New instance of validation result
+     */
+    public static final ValidationResult fromMessages( Collection<? extends ValidationMessage> messages ) {
+        return new ValidationResult().addAll(messages);
+    }
+
+    /**
+     * Factory method to create validation result out of several validation results
+     * @param results results
+     * @return New instance of validation result, combining all into one
+     */
+    public static final ValidationResult fromResults( ValidationResult... results ) {
+        return new ValidationResult().combineAll(results);
+    }
+
+    /**
+     * Factory method to create validation result out of collection of validation results
+     * @param results results
+     * @return New instance of validation result, combining all into one
+     */
+    public static final ValidationResult fromResults( Collection<ValidationResult> results ) {
+        return new ValidationResult().combineAll(results);
+    }
+
+    /**
+     * Creates a copy of validation result
+     * @return copy of validation result
+     */
+    public ValidationResult copy() {
+        return ValidationResult.fromMessages(getMessages());
+    }
+
+    /**
+     * Add one message to validation result
+     * @param message validation message
+     * @return updated validation result
+     */
+    public ValidationResult add( ValidationMessage message ) {
+
+        if ( message != null ) {
+            switch( message.getSeverity() ) {
+                case ERROR  : errors.add( message); break;
+                case WARNING: warnings.add(message); break;
+            }
+        }
+
+        return this;
+    }
+
+    /**
+     * Add one message to validation result with condition
+     * @param target validation target
+     * @param text message text
+     * @param severity message severity
+     * @param condition condition on which message will be added 
+     * @return updated validation result
+     */
+    public ValidationResult addMessageIf( Control target, String text, Severity severity, boolean condition) {
+        return  condition? add( new SimpleValidationMessage(target, text, severity)): this;
+    }
+
+    /**
+     * Add one error to validation result with condition
+     * @param target validation target
+     * @param text message text
+     * @param condition condition on which error will be added 
+     * @return updated validation result
+     */
+    public ValidationResult addErrorIf( Control target, String text, boolean condition) {
+        return addMessageIf(target,text,Severity.ERROR,condition);
+    }
+
+    /**
+     * Add one warning to validation result with condition
+     * @param target validation target
+     * @param text message text
+     * @param condition condition on which warning will be added 
+     * @return updated validation result
+     */
+    public ValidationResult addWarningIf( Control target, String text, boolean condition) {
+        return addMessageIf(target,text,Severity.WARNING,condition);
+    }
+
+    /**
+     * Add collection of validation messages
+     * @param messages
+     * @return updated validation result
+     */
+    public ValidationResult addAll( Collection<? extends ValidationMessage> messages ) {
+        messages.stream().forEach( msg-> add(msg));
+        return this;
+    }
+
+    /**
+     * Add several validation messages
+     * @param messages
+     * @return updated validation result
+     */
+    public ValidationResult addAll( ValidationMessage... messages ) {
+        return addAll(Arrays.asList(messages));
+    }
+
+    /**
+     * Combine validation result with another. This will create a new instance of combined validation result
+     * @param validationResult
+     * @return new instance of combined validation result
+     */
+    public ValidationResult combine( ValidationResult validationResult ) {
+        return validationResult == null? copy(): copy().addAll(validationResult.getMessages());
+    }
+
+    /**
+     * Combine validation result with others. This will create a new instance of combined validation result
+     * @param validationResults
+     * @return new instance of combined validation result
+     */
+    public ValidationResult combineAll( Collection<ValidationResult> validationResults ) {
+        return validationResults.stream().reduce(copy(), (x,r) -> {
+            return r == null? x: x.addAll(r.getMessages());
+        });
+    }
+
+    /**
+     * Combine validation result with others. This will create a new instance of combined validation result
+     * @param validationResults
+     * @return new instance of combined validation result
+     */
+    public ValidationResult combineAll( ValidationResult... validationResults ) {
+        return combineAll( Arrays.asList(validationResults));
+    }
+
+    /**
+     * Retrieve errors represented by validation result
+     * @return collection of errors
+     */
+    public Collection<ValidationMessage> getErrors() {
+        return Collections.unmodifiableList(errors);
+    }
+
+    /**
+     * Retrieve warnings represented by validation result
+     * @return collection of warnings
+     */
+    public Collection<ValidationMessage> getWarnings() {
+        return Collections.unmodifiableList(warnings);
+    }
+
+    /**
+     * Retrieve all messages represented by validation result
+     * @return collection of messages
+     */
+    public Collection<ValidationMessage> getMessages() {
+        List<ValidationMessage> messages = new ArrayList<>();
+        messages.addAll(errors);
+        messages.addAll(warnings);
+        return Collections.unmodifiableList(messages);
+    }
+
+}
diff --git a/src/org/controlsfx/validation/ValidationSupport.java b/src/org/controlsfx/validation/ValidationSupport.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd70c0682c4033498237042965efada8e2eadcb7
--- /dev/null
+++ b/src/org/controlsfx/validation/ValidationSupport.java
@@ -0,0 +1,329 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation;
+
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+import javafx.application.Platform;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyBooleanProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.ReadOnlyObjectWrapper;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.MapChangeListener;
+import javafx.collections.ObservableMap;
+import javafx.collections.ObservableSet;
+import javafx.scene.control.Control;
+import javafx.util.Callback;
+
+import org.controlsfx.tools.ValueExtractor;
+import org.controlsfx.validation.decoration.GraphicValidationDecoration;
+import org.controlsfx.validation.decoration.ValidationDecoration;
+
+/**
+ * Provides validation support for UI components. The idea is create an instance of this class the component group, usually a panel.<br>
+ * Once created, {@link Validator}s can be registered for components, to provide the validation:
+ * 
+ *     <pre>
+ *        ValidationSupport validationSupport = new ValidationSupport();
+ *        validationSupport.registerValidator(textField, Validator.createEmptyValidator("Text is required"));
+ *        validationSupport.registerValidator(combobox, Validator.createEmptyValidator( "ComboBox Selection required"));
+ *        validationSupport.registerValidator(checkBox, (Control c, Boolean newValue) -&gt;
+ *        	    ValidationResult.fromErrorIf( c, "Checkbox should be checked", !newValue)
+ *         );
+ *     </pre>
+ *     
+ *  validationResultProperty provides an ability to react on overall validation result changes:
+ *  <pre>
+ *     validationSupport.validationResultProperty().addListener( (o, oldValue, newValue) -&gt;
+        	 messageList.getItems().setAll(newValue.getMessages()));
+ *  </pre>   
+ *  
+ *  Standard JavaFX UI controls are supported out of the box. There is also an ability to add support for custom controls.
+ *  To do that "observable value extractor" should be added for specific controls. Such "extractor" consists of two functional interfaces:
+ *  a {@link Predicate} to check the applicability of the control and a {@link Callback} to extract control's observable value. 
+ *  Here is an sample of internal registration of such "extractor" for  a few  controls :
+ *  <pre>
+ *     ValueExtractor.addObservableValueExtractor( c -&gt; c instanceof TextInputControl, c -&gt; ((TextInputControl)c).textProperty());
+ *     ValueExtractor.addObservableValueExtractor( c -&gt; c instanceof ComboBox,         c -&gt; ((ComboBox&lt;?&gt;)c).getValue());
+ *  </pre>
+ *   
+ */
+public class ValidationSupport {
+    
+
+    private static final String CTRL_REQUIRED_FLAG    = "$org.controlsfx.validation.required$"; //$NON-NLS-1$
+    
+    /**
+     * Set control's required flag
+     * @param c control
+     * @param required flag
+     */
+    public static void setRequired( Control c, boolean required ) {
+        c.getProperties().put(CTRL_REQUIRED_FLAG, required);
+    }
+
+    /**
+     * Check control's required flag
+     * @param c control
+     * @return true if required 
+     */
+    public static boolean isRequired( Control c ) {
+        Object value = c.getProperties().get(CTRL_REQUIRED_FLAG);
+        return value instanceof Boolean? (Boolean)value: false;
+    }
+
+    private ObservableSet<Control> controls = FXCollections.observableSet();
+    private ObservableMap<Control,ValidationResult> validationResults = 
+            FXCollections.observableMap(new WeakHashMap<>());
+
+    
+    private AtomicBoolean dataChanged = new AtomicBoolean(false);
+    
+    /**
+     * Creates validation support instance. <br>
+     * If initial decoration is desired invoke {@link #initInitialDecoration()}.
+     */
+    public ValidationSupport() {
+
+        validationResultProperty().addListener( (o, oldValue, validationResult) -> {
+            invalidProperty.set(!validationResult.getErrors().isEmpty());
+            redecorate();
+        });
+    	
+        // notify validation result observers
+        validationResults.addListener( (MapChangeListener.Change<? extends Control, ? extends ValidationResult> change) ->
+        	validationResultProperty.set(ValidationResult.fromResults(validationResults.values()))
+        );
+
+    }
+    
+    /**
+     * Activates the initial decoration of validated controls. <br>
+     * By default the decoration will only be applied after the first change of one validated controls value.
+     */
+    public void initInitialDecoration() {
+        dataChanged.set(true);
+        redecorate();
+    }
+
+    /**
+     * Redecorates all known components
+     * Only decorations related to validation are affected
+     */
+    // TODO needs optimization
+    public void redecorate() {
+        Optional<ValidationDecoration> odecorator = Optional.ofNullable(getValidationDecorator());
+        for (Control target : getRegisteredControls()) {
+            odecorator.ifPresent( decorator -> {
+            	decorator.removeDecorations(target);
+                decorator.applyRequiredDecoration(target);
+                if ( dataChanged.get() && isErrorDecorationEnabled()) {
+                	getHighestMessage(target).ifPresent(msg -> decorator.applyValidationDecoration(msg));
+                }
+            });
+        }
+    }
+    
+    private BooleanProperty errorDecorationEnabledProperty = new SimpleBooleanProperty(true) {
+    	protected void invalidated() {
+    		redecorate();
+    	};
+    };
+    
+    public BooleanProperty errorDecorationEnabledProperty() {
+    	return errorDecorationEnabledProperty;
+    }
+    
+    public void setErrorDecorationEnabled(boolean enabled) {
+		errorDecorationEnabledProperty.set(enabled);
+	}
+    
+    private boolean isErrorDecorationEnabled() {
+    	return errorDecorationEnabledProperty.get();
+	}
+    
+    
+
+    private ReadOnlyObjectWrapper<ValidationResult> validationResultProperty = 
+            new ReadOnlyObjectWrapper<>();
+
+
+    /**
+     * Retrieves current validation result
+     * @return validation result
+     */
+    public ValidationResult getValidationResult() {
+        return validationResultProperty.get();
+    }
+
+    /**
+     * Can be used to track validation result changes 
+     * @return The Validation result property.
+     */
+    public ReadOnlyObjectProperty<ValidationResult> validationResultProperty() {
+        return validationResultProperty.getReadOnlyProperty();
+    }
+
+    private BooleanProperty invalidProperty = new SimpleBooleanProperty();
+
+    /**
+     * Returns current validation state. 
+     * @return true if there is at least one error
+     */
+    public Boolean isInvalid() {
+        return invalidProperty.get();
+    }
+
+    /**
+     * Validation state property 
+     * @return validation state property
+     */
+    public ReadOnlyBooleanProperty invalidProperty() {
+        return invalidProperty;
+    }
+
+
+    private ObjectProperty<ValidationDecoration> validationDecoratorProperty =
+            new SimpleObjectProperty<ValidationDecoration>(this, "validationDecorator", new GraphicValidationDecoration()) { //$NON-NLS-1$
+        @Override protected void invalidated() {
+            // when the decorator changes, rerun the decoration to update the visuals immediately.
+            redecorate();
+        }
+    };
+
+    /**
+     * @return The Validation decorator property
+     */
+    public ObjectProperty<ValidationDecoration> validationDecoratorProperty() {
+        return validationDecoratorProperty;
+    }
+
+    /**
+     * Returns current validation decorator
+     * @return current validation decorator or null if none
+     */
+    public ValidationDecoration getValidationDecorator() {
+        return validationDecoratorProperty.get();
+    }
+
+    /**
+     * Sets new validation decorator
+     * @param decorator new validation decorator. Null value is valid - no decoration will occur
+     */
+    public void setValidationDecorator( ValidationDecoration decorator ) {
+        validationDecoratorProperty.set(decorator);
+    }
+
+
+    /**
+     * Registers {@link Validator} for specified control with additional possiblity to mark control as required or not.
+     * @param c control to validate
+     * @param required true if controls should be required
+     * @param validator {@link Validator} to be used
+     * @return true if registration is successful
+     */
+    @SuppressWarnings("unchecked")
+    public <T> boolean registerValidator( final Control c, boolean required, final Validator<T> validator  ) {
+    	
+    	Optional.ofNullable(c).ifPresent( ctrl -> {
+    		ctrl.getProperties().addListener( new MapChangeListener<Object,Object>(){
+
+				@Override
+				public void onChanged(
+						javafx.collections.MapChangeListener.Change<? extends Object, ? extends Object> change) {
+					
+					if ( CTRL_REQUIRED_FLAG.equals(change.getKey())) {
+						redecorate();
+					}
+				}
+
+    		});
+    	});
+    	
+        setRequired( c, required );
+
+        return ValueExtractor.getObservableValueExtractor(c).map( e -> {
+
+            ObservableValue<T> observable = (ObservableValue<T>) e.call(c);
+
+            Consumer<T> updateResults = value -> { 
+                Platform.runLater(() -> validationResults.put(c, validator.apply(c, value)));
+            };
+
+            controls.add(c);
+
+            observable.addListener( (o,oldValue,newValue) -> {
+            	dataChanged.set(true);
+            	updateResults.accept(newValue);
+            });
+            updateResults.accept(observable.getValue());
+
+            return e;
+
+        }).isPresent();
+    }
+
+    /**
+     * Registers {@link Validator} for specified control and makes control required
+     * @param c control to validate
+     * @param validator {@link Validator} to be used
+     * @return true if registration is successful
+     */
+    public <T> boolean registerValidator( final Control c, final Validator<T> validator  ) {
+        return registerValidator(c, true, validator);
+    }
+
+    /**
+     * Returns currently registered controls
+     * @return set of currently registered controls
+     */
+    public Set<Control> getRegisteredControls() {
+        return Collections.unmodifiableSet(controls);
+    }
+
+    /**
+     * Returns optional highest severity message for a control
+     * @param target control
+     * @return Optional highest severity message for a control
+     */
+    public Optional<ValidationMessage> getHighestMessage(Control target) {
+    	return Optional.ofNullable(validationResults.get(target)).flatMap( result ->
+    	   result.getMessages().stream().max(ValidationMessage.COMPARATOR)   
+    	);
+    }
+}
diff --git a/src/org/controlsfx/validation/Validator.java b/src/org/controlsfx/validation/Validator.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a7aeaae73e23acd6a9311495c525c4bef0999e5
--- /dev/null
+++ b/src/org/controlsfx/validation/Validator.java
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation;
+
+import java.util.Collection;
+import java.util.function.BiFunction;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javafx.scene.control.Control;
+
+/**
+ * Interface defining the contract for validation of specific component
+ * This interface is a {@link BiFunction} which when given the control and its current value 
+ * computes the validation result 
+ * 
+ * @param <T> type of the controls value
+ */
+public interface Validator<T> extends BiFunction<Control, T, ValidationResult> {
+    
+    /**
+     * Combines the given validators into a single Validator instance. 
+     * @param validators the validators to combine
+     * @return a Validator instance
+     */
+    @SafeVarargs
+    static <T> Validator<T> combine(Validator<T>... validators) {
+        return (control, value) -> Stream.of(validators)
+            .map(validator -> validator.apply(control, value))
+            .collect(Collectors.reducing(new ValidationResult(), ValidationResult::combine));
+    }
+
+    /**
+     * Factory method to create a validator, which checks if value exists. 
+     * @param message text of a message to be created if value is invalid
+     * @param severity severity of a message to be created if value is invalid
+     * @return new validator
+     */
+    public static <T> Validator<T> createEmptyValidator(final String message, final Severity severity) {
+        return (c, value) -> {
+            boolean condition = value instanceof String ? value.toString().trim().isEmpty() : value == null;
+            return ValidationResult.fromMessageIf(c, message, severity, condition);
+        };
+    }
+
+    /**
+     * Factory method to create a validator, which checks if value exists. 
+     * Error is created if not if value does not exist 
+     * @param message of a error to be created if value is invalid
+     * @return new validator
+     */
+    public static <T> Validator<T> createEmptyValidator(final String message) {
+        return createEmptyValidator(message, Severity.ERROR);
+    }
+
+    /**
+     * Factory method to create a validator, which if value exists in the provided collection. 
+     * @param values text of a message to be created if value is not found
+     * @param severity severity of a message to be created if value is found
+     * @return new validator
+     */
+    public static <T> Validator<T> createEqualsValidator(final String message, final Severity severity, final Collection<T> values) {
+        return (c, value) -> ValidationResult.fromMessageIf(c,message,severity, !values.contains(value));
+    }
+
+    /**
+     * Factory method to create a validator, which checks if value exists in the provided collection. 
+     * Error is created if not found 
+     * @param message text of a error to be created if value is not found
+     * @param values
+     * @return new validator
+     */
+    public static <T> Validator<T> createEqualsValidator(final String message, final Collection<T> values) {
+        return createEqualsValidator(message, Severity.ERROR, values);
+    }
+    
+    /**
+     * Factory method to create a validator, which evaluates the value validity with a given predicate.
+     * Error is created if the evaluation is <code>false</code>.
+     * @param message text of a message to be created if value is invalid
+     * @param predicate the predicate to be used for the value validity evaluation.
+     * @return new validator
+     */
+    static <T> Validator<T> createPredicateValidator(Predicate<T> predicate, String message) {
+        return createPredicateValidator(predicate, message, Severity.ERROR);
+    }
+    
+    /**
+     * Factory method to create a validator, which evaluates the value validity with a given predicate.
+     * Error is created if the evaluation is <code>false</code>.
+     * @param message text of a message to be created if value is invalid
+     * @param predicate the predicate to be used for the value validity evaluation.
+     * @param severity severity of a message to be created if value is invalid
+     * @return new validator
+     */
+    static <T> Validator<T> createPredicateValidator(Predicate<T> predicate, String message, Severity severity) {
+        return (control, value) -> ValidationResult.fromMessageIf(
+            control, message,
+            severity,
+            predicate.test(value) == false);
+    }
+
+    /**
+     * Factory method to create a validator, which checks the value against a given regular expression.
+     * Error is created if the value is <code>null</code> or the value does not match the pattern.
+     * @param message text of a message to be created if value is invalid
+     * @param regex the regular expression the value has to match
+     * @param severity severity of a message to be created if value is invalid
+     * @return new validator
+     */
+    public static Validator<String> createRegexValidator(final String message, final String regex, final Severity severity) {
+        return (c, value) -> {
+            boolean condition = value == null ? true : !Pattern.matches(regex, value);
+            return ValidationResult.fromMessageIf(c, message, severity, condition);
+        };
+    }
+    
+    /**
+     * Factory method to create a validator, which checks the value against a given regular expression.
+     * Error is created if the value is <code>null</code> or the value does not match the pattern.
+     * @param message text of a message to be created if value is invalid
+     * @param regex the regular expression the value has to match
+     * @param severity severity of a message to be created if value is invalid
+     * @return new validator
+     */
+    public static Validator<String> createRegexValidator(final String message, final Pattern regex, final Severity severity) {
+        return (c, value) -> {
+            boolean condition = value == null ? true : !regex.matcher(value).matches();
+            return ValidationResult.fromMessageIf(c, message, severity, condition);
+        };
+    }
+}
diff --git a/src/org/controlsfx/validation/decoration/AbstractValidationDecoration.java b/src/org/controlsfx/validation/decoration/AbstractValidationDecoration.java
new file mode 100644
index 0000000000000000000000000000000000000000..f717852cc77c31e75538827ce683099c2eacb964
--- /dev/null
+++ b/src/org/controlsfx/validation/decoration/AbstractValidationDecoration.java
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation.decoration;
+
+import java.util.Collection;
+import java.util.List;
+
+import javafx.scene.control.Control;
+
+import org.controlsfx.control.decoration.Decoration;
+import org.controlsfx.control.decoration.Decorator;
+import org.controlsfx.validation.ValidationMessage;
+import org.controlsfx.validation.ValidationSupport;
+
+/**
+ * Implements common functionality for validation decorators.
+ * This class intended as a base for custom validation decorators   
+ * Custom validation decorator should define only two things:
+ * how 'validation' and 'required' decorations should be created
+ * <br>
+ * See {@link GraphicValidationDecoration} or {@link StyleClassValidationDecoration} for examples of such implementations.
+ * 
+ */
+public abstract class AbstractValidationDecoration implements ValidationDecoration {
+	
+	private static final String VALIDATION_DECORATION = "$org.controlsfx.decoration.vaidation$"; //$NON-NLS-1$
+	
+	private static boolean isValidationDecoration( Decoration decoration) {
+        return decoration != null && decoration.getProperties().get(VALIDATION_DECORATION) == Boolean.TRUE;
+    }
+
+	private static void setValidationDecoration( Decoration decoration ) {
+        if ( decoration != null ) {
+            decoration.getProperties().put(VALIDATION_DECORATION, Boolean.TRUE);
+        }
+    }
+
+	protected abstract Collection<Decoration> createValidationDecorations(ValidationMessage message);
+	protected abstract Collection<Decoration> createRequiredDecorations(Control target);
+	
+	/**
+	 * Removes all validation related decorations from the target
+	 * @param target control
+	 */
+	@Override
+	public void removeDecorations(Control target) {
+		 List<Decoration> decorations = Decorator.getDecorations(target);
+        if ( decorations != null ) {
+        	// conversion to array is a trick to prevent concurrent modification exception 
+            for ( Decoration d: Decorator.getDecorations(target).toArray(new Decoration[0]) ) {
+            	if (isValidationDecoration(d)) Decorator.removeDecoration(target, d);
+            }
+        }
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see org.controlsfx.validation.decorator.ValidationDecorator#applyValidationDecoration(org.controlsfx.validation.ValidationMessage)
+	 */
+	@Override
+	public void applyValidationDecoration(ValidationMessage message) {
+		createValidationDecorations(message).stream().forEach( d -> decorate( message.getTarget(), d ));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.controlsfx.validation.decorator.ValidationDecorator#applyRequiredDecoration(javafx.scene.control.Control)
+	 */
+	@Override
+	public void applyRequiredDecoration(Control target) {
+		if ( ValidationSupport.isRequired(target)) { 
+			createRequiredDecorations(target).stream().forEach( d -> decorate( target, d ));
+		}
+	}
+	
+	private void decorate( Control target, Decoration d ) {
+		setValidationDecoration(d); // mark as validation specific decoration
+        Decorator.addDecoration(target, d);
+	}
+
+}
diff --git a/src/org/controlsfx/validation/decoration/CompoundValidationDecoration.java b/src/org/controlsfx/validation/decoration/CompoundValidationDecoration.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ba3722a668ce64212952493d56b3c1830330add
--- /dev/null
+++ b/src/org/controlsfx/validation/decoration/CompoundValidationDecoration.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation.decoration;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javafx.scene.control.Control;
+
+import org.controlsfx.control.decoration.Decoration;
+import org.controlsfx.validation.ValidationMessage;
+
+/**
+ * Validation decoration to combine several existing decorations into one.
+ * Here is example of combining {@link GraphicValidationDecoration} and  {@link StyleClassValidationDecoration} 
+ * <br> <br>
+ * <img src="CompoundValidationDecoration.png" alt="Screenshot of CompoundValidationDecoration">  
+ *   
+ * 
+ */
+public class CompoundValidationDecoration extends AbstractValidationDecoration {
+
+    private final Set<ValidationDecoration> decorators = new HashSet<>();
+
+    /**
+     * Creates an instance of validator using a collection of validators
+     * @param decorators collection of validators
+     */
+    public CompoundValidationDecoration(Collection<ValidationDecoration> decorators) {
+        this.decorators.addAll(decorators); 
+    }
+
+    /**
+     * Creates an instance of validator using a set of validators
+     * @param decorators set of validators
+     */
+    public CompoundValidationDecoration(ValidationDecoration... decorators) {
+        this(Arrays.asList(decorators));
+    }	
+
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+	public void applyRequiredDecoration(Control target) {
+		this.decorators.stream().forEach( d -> d.applyRequiredDecoration(target)); 
+	}
+	
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+	public void applyValidationDecoration(ValidationMessage message) {
+		this.decorators.stream().forEach( d -> d.applyValidationDecoration(message)); 
+	}
+
+	@Override
+	protected Collection<Decoration> createValidationDecorations(ValidationMessage message) {
+		return Collections.emptyList();
+	}
+
+	@Override
+	protected Collection<Decoration> createRequiredDecorations(Control target) {
+		return Collections.emptyList();
+	}
+}
diff --git a/src/org/controlsfx/validation/decoration/GraphicValidationDecoration.java b/src/org/controlsfx/validation/decoration/GraphicValidationDecoration.java
new file mode 100644
index 0000000000000000000000000000000000000000..c405ceadf3970b157f8edd7d2efbacb13cd1a05e
--- /dev/null
+++ b/src/org/controlsfx/validation/decoration/GraphicValidationDecoration.java
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation.decoration;
+
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.Control;
+import javafx.scene.control.Label;
+import javafx.scene.control.Tooltip;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+
+import org.controlsfx.control.decoration.Decoration;
+import org.controlsfx.control.decoration.GraphicDecoration;
+import org.controlsfx.validation.Severity;
+import org.controlsfx.validation.ValidationMessage;
+
+/**
+ * Validation decorator to decorate validation state using images.
+ * <br>
+ * Validation icons are shown in the bottom-left corner of the control as it is seems to be the most
+ * logical location for such information.
+ * Required components are marked at the top-left corner with small red triangle.
+ * Here is example of such decoration 
+ * <br> <br>
+ * <img src="GraphicValidationDecorationWithTooltip.png" alt="Screenshot of GraphicValidationDecoration">  
+ * 
+ */
+public class GraphicValidationDecoration extends AbstractValidationDecoration {
+
+    // TODO we shouldn't hardcode this - defer to CSS eventually
+	
+    private static final Image ERROR_IMAGE = new Image(GraphicValidationDecoration.class.getResource("/impl/org/controlsfx/control/validation/decoration-error.png").toExternalForm()); //$NON-NLS-1$
+    private static final Image WARNING_IMAGE = new Image(GraphicValidationDecoration.class.getResource("/impl/org/controlsfx/control/validation/decoration-warning.png").toExternalForm()); //$NON-NLS-1$
+    private static final Image REQUIRED_IMAGE = new Image(GraphicValidationDecoration.class.getResource("/impl/org/controlsfx/control/validation/required-indicator.png").toExternalForm()); //$NON-NLS-1$
+
+    private static final String SHADOW_EFFECT = "-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 10, 0, 0, 0);"; //$NON-NLS-1$
+    private static final String POPUP_SHADOW_EFFECT = "-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 5, 0, 0, 5);"; //$NON-NLS-1$
+    private static final String TOOLTIP_COMMON_EFFECTS = "-fx-font-weight: bold; -fx-padding: 5; -fx-border-width:1;"; //$NON-NLS-1$
+    
+    private static final String ERROR_TOOLTIP_EFFECT = POPUP_SHADOW_EFFECT + TOOLTIP_COMMON_EFFECTS
+            + "-fx-background-color: FBEFEF; -fx-text-fill: cc0033; -fx-border-color:cc0033;"; //$NON-NLS-1$
+
+    private static final String WARNING_TOOLTIP_EFFECT = POPUP_SHADOW_EFFECT + TOOLTIP_COMMON_EFFECTS
+            + "-fx-background-color: FFFFCC; -fx-text-fill: CC9900; -fx-border-color: CC9900;"; //$NON-NLS-1$
+
+    /**
+     * Creates default instance
+     */
+    public GraphicValidationDecoration() {
+
+    }
+
+    // TODO write javadoc that users should override these methods to customise
+    // the error / warning / success nodes to use 
+    protected Node createErrorNode() {
+        return new ImageView(ERROR_IMAGE);
+    }
+
+    protected Node createWarningNode() {
+        return new ImageView(WARNING_IMAGE);
+    }
+
+    private Node createDecorationNode(ValidationMessage message) {
+        Node graphic = Severity.ERROR == message.getSeverity() ? createErrorNode() : createWarningNode();
+        graphic.setStyle(SHADOW_EFFECT);
+        Label label = new Label();
+        label.setGraphic(graphic);
+        label.setTooltip(createTooltip(message));
+        label.setAlignment(Pos.CENTER);
+        return label;
+    }
+
+    protected Tooltip createTooltip(ValidationMessage message) {
+        Tooltip tooltip = new Tooltip(message.getText());
+        tooltip.setOpacity(.9);
+        tooltip.setAutoFix(true);
+        tooltip.setStyle( Severity.ERROR == message.getSeverity()? ERROR_TOOLTIP_EFFECT: WARNING_TOOLTIP_EFFECT);
+        return tooltip;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+	protected Collection<Decoration> createValidationDecorations(ValidationMessage message) {
+    	return Arrays.asList(new GraphicDecoration(createDecorationNode(message),Pos.BOTTOM_LEFT));
+	}
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+	protected Collection<Decoration> createRequiredDecorations(Control target) {
+    	return Arrays.asList(new GraphicDecoration(new ImageView(REQUIRED_IMAGE),Pos.TOP_LEFT, REQUIRED_IMAGE.getWidth()/2, REQUIRED_IMAGE.getHeight()/2));
+	}
+    
+    
+}
diff --git a/src/org/controlsfx/validation/decoration/StyleClassValidationDecoration.java b/src/org/controlsfx/validation/decoration/StyleClassValidationDecoration.java
new file mode 100644
index 0000000000000000000000000000000000000000..01f0b81e257c86152e21e2fc22d121b346b2fed4
--- /dev/null
+++ b/src/org/controlsfx/validation/decoration/StyleClassValidationDecoration.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2014, 2015, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation.decoration;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import javafx.scene.control.Control;
+
+import org.controlsfx.control.decoration.Decoration;
+import org.controlsfx.control.decoration.StyleClassDecoration;
+import org.controlsfx.validation.Severity;
+import org.controlsfx.validation.ValidationMessage;
+
+/**
+ * Validation decorator to decorate component validation state using two
+ * CSS classes for errors and warnings.
+ * Here is example of such decoration 
+ * <br> <br>
+ * <img src="StyleClassValidationDecoration.png" alt="Screenshot of StyleClassValidationDecoration">  
+ */
+public class StyleClassValidationDecoration extends AbstractValidationDecoration {
+
+    private final String errorClass;
+    private final String warningClass;
+
+    /**
+     * Creates a default instance of a decorator
+     */
+    public StyleClassValidationDecoration() {
+        this(null,null);
+    }
+
+    /**
+     * Creates an instance of validator using custom class names
+     * @param errorClass class name for error decoration
+     * @param warningClass class name for warning decoration
+     */
+    public StyleClassValidationDecoration(String errorClass, String warningClass) {
+        this.errorClass = errorClass != null? errorClass : "error"; //$NON-NLS-1$
+        this.warningClass = warningClass != null? warningClass : "warning";	 //$NON-NLS-1$
+    }
+
+
+	@Override
+	protected Collection<Decoration> createValidationDecorations(ValidationMessage message) {
+		return Arrays.asList(new StyleClassDecoration( Severity.ERROR == message.getSeverity()? errorClass:warningClass));
+	}
+
+	@Override
+	protected Collection<Decoration> createRequiredDecorations(Control target) {
+		return Collections.emptyList();
+	}
+    
+}
diff --git a/src/org/controlsfx/validation/decoration/ValidationDecoration.java b/src/org/controlsfx/validation/decoration/ValidationDecoration.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6fab8c9cd623edac13be4c2d0f677a71e3cf5a3
--- /dev/null
+++ b/src/org/controlsfx/validation/decoration/ValidationDecoration.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2014, ControlsFX
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of ControlsFX, any associated website, nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.controlsfx.validation.decoration;
+
+import javafx.scene.control.Control;
+
+import org.controlsfx.validation.ValidationMessage;
+
+/**
+ * Contract for validation decorators.
+ * Classes implementing this interface are used for decorating components with error/warning conditions, if such exists.
+ * They also used for marking 'required' components.
+ */
+public interface ValidationDecoration {
+
+    /**
+     * Removes all validation specific decorations from the target control.
+     * Non-validation specific decorations are left untouched.
+     * @param target
+     */
+    void removeDecorations(Control target);
+	
+    /**
+     * Applies validation decoration based on a given validation message
+     * @param message validation message
+     */
+    void applyValidationDecoration(ValidationMessage message);
+    
+    
+    /**
+     * Applies 'required' decoration to a given control
+     * @param target control
+     */
+    void applyRequiredDecoration(Control target);
+}
diff --git a/src/org/controlsfx/validation/decoration/package-info.java b/src/org/controlsfx/validation/decoration/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..de37a2554ae5fefa5a1682b03ca179bf6e624524
--- /dev/null
+++ b/src/org/controlsfx/validation/decoration/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * A package containing decoration API specific to the validation framework.
+ */
+package org.controlsfx.validation.decoration;
\ No newline at end of file
diff --git a/src/org/controlsfx/validation/package-info.java b/src/org/controlsfx/validation/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..db054a129430c2f8739bce87eca7772a23af6cb1
--- /dev/null
+++ b/src/org/controlsfx/validation/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * A package containing validation-related API (that is, API to allow for developers
+ * to easily validate user input, and to provide visual feedback on the results).
+ */
+package org.controlsfx.validation;
\ No newline at end of file