diff --git a/.gitignore b/.gitignore
index d7bb865cb34775dc08bf9caa6caa8519008c9d7f..5003f73cc338171ef21b699e8a10f990d157fb75 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+/doc/*.pdf
 /.doc_plantuml
 /.support
 /.support_plantuml
diff --git a/CODING.md b/doc/CODING.md
similarity index 71%
rename from CODING.md
rename to doc/CODING.md
index 8b499af70ad075105aa96ec083f09219060b46a0..2da8713423e7fcc07672759222488991b1221767 100644
--- a/CODING.md
+++ b/doc/CODING.md
@@ -72,107 +72,6 @@ DELETE
    * HTML Code:
    
      <button type="button" class="record-delete" data-sip={{SIP}} ><span class="glyphicon glyphicon-trash"></span></button>
-
-USER INTERFACE
-==============
-
-Button status
--------------
-* Form modified:
-  * Buttons enabled: Save, Close, New, Delete
-  * Button disable: -
-  
-* Form not modified:
-  * Buttons enabled: Close, New, Delete
-  * Button disabled: Save
-
-Save Button 
------------
-
-* User presses the button
-  * Reset all validation states
-  * Client validates HTML Form
-  * Form is submitted to server
-    * Success: 
-       * Show message provided by server
-       * Current formelements and data will be reloaded.
-       * Process server reponse 'redirect':
-           * 'client': No redirect.
-           * 'no': No redirect.
-           * 'url': Redirect to URL
-    * Failure: Happens on communication errors, if data validation fails, form actions fails or saving data fails. 
-       * Show error message.
-       * Client: Ignore server reponse 'redirect'. Client stays on current page.
-    
-
-Close Button
-------------
-* User presses the button
-  * Form not modified by user: Client redirects to previous page.
-  * Form modified by user: Ask User 'You have unsaved changes. Do you want to close?'
-    * Yes: Client redirects to previous page.
-    * No: Client stays on current page.
-    * Save & Close: 
-      * Client reset all validation states
-      * Client validates HTML Form
-      * Client submits form to server.
-      * Success: Process server response 'redirect':
-        * 'client': Client shows previous page.
-        * 'no': No redirect.
-        * 'url': Redirect to URL
-      * Failure: Happens on communication errors, if data validation fails, form actions fails or saving data fails. 
-        * Show error message. 
-        * Client: No redirect. Ignore server reponse 'redirect'.
-
-Delete Button: Main record
---------------------------
-* User presses the button. Ask User 'Do you really want to delete the record?
-  * Yes: 
-    * Delete record on server.
-    * Process server reponse 'redirect':
-      * 'client': Client redirects to previous page.
-      * 'no': Error message.
-      * 'url': Redirect to URL
-  * No:
-    * Client does not delete record on server.
-    * No redirect. Client stays on current page.
-
-New Button
-----------
-* User presses the button
-  * Form not modified by user: Client redirects to href url.
-  * Form modified by user: Ask User 'You have unsaved changes. Do you want to save first?'
-    * Yes:
-      * Client reset all validation states
-      * Client validates HTML Form
-      * Form is submitted to server
-        * Success:
-          * Client: Ignore server reponse 'redirect'. Client redirects to href url.
-        * Failure: Happens on communication errors, if data validation fails, form actions fails or saving data fails. 
-           * Show error message.
-           * Client: Ignore server reponse 'redirect'. Client stays on current page.
-    * No: 
-      * Client does not save the modified record.
-      * Client redirects to href url.
-    * Cancel:
-      * Client does not save the modified record.
-      * Client stays on current page.
-  
-
-File Handling: Upload
----------------------
-* No previous uploaded file present
-  1. User presses the Browse button
-    1. User selects file
-      1. File is uploaded to qfq immediately
-      1. Browse button gets disabled and hidden
-      1. File delete button is shown
-    1. User cancels file selection
-      1. no action
-* Previous uploaded file present
-  1. User deletes file
-    1. File delete button gets disabled and hidden
-    1. Browse button gets enabled and displayed
   
 Form Build (load)
 .................
@@ -314,4 +213,4 @@ Checkbox
         </label>
     </div>
     
-    
\ No newline at end of file
+    
diff --git a/doc/HTML.md b/doc/HTML.md
new file mode 100644
index 0000000000000000000000000000000000000000..d7d3266f03759c60187b40e35e44d6675f1b4863
--- /dev/null
+++ b/doc/HTML.md
@@ -0,0 +1,39 @@
+# HTML
+
+This document explains the HTML markup used by QFQ.
+
+## Hooks
+
+Hooks are used on by the Client to gather information required for
+asynchronous requests and to add predefined event handlers to HTML Elements.
+
+
+### form.data-toggle="validator"
+
+Adding the attribute `data-toggle="validator"` to a `<form>` element,
+enables the Bootstrap Validator on that HTML Form.
+
+
+### .data-sip
+
+Asynchronous requests require to pass a SID to the Server. Elements
+triggering an asynchronous request, may gather the SIP from the
+`data-sip` attribute assigned to the HTML Form Element.
+
+
+### .class="record-delete"
+
+HTML Form Buttons having the class `record-delete` set, will get an
+`onclick` handler attached by `QfqNS.QfqRecordList`. Each `<button>`
+also requires an `data-sip` attribute.
+
+
+### .data-load=""
+
+HTML Form Elements having the attribute `data-load`, will trigger a
+call to `api/load.php` upon change.
+
+### id="save-button"
+### id="close-button"
+### id="delete-button"
+### id="form-new-button"
diff --git a/LAYOUT.md b/doc/LAYOUT.md
similarity index 100%
rename from LAYOUT.md
rename to doc/LAYOUT.md
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b9d13ff192becbd391749e0c62edcdffb0d78717
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,9 @@
+SOURCES = CODING.md HTML.md PROTOCOL.md UI.md LAYOUT.md
+PDFDOCS = $(patsubst %.md,%.pdf,$(SOURCES))
+
+all: $(PDFDOCS)
+
+.md.pdf:
+	pandoc -o $@ $<
+
+.SUFFIXES: .md .pdf
diff --git a/PROTOCOL.md b/doc/PROTOCOL.md
similarity index 100%
rename from PROTOCOL.md
rename to doc/PROTOCOL.md
diff --git a/doc/UI.md b/doc/UI.md
new file mode 100644
index 0000000000000000000000000000000000000000..23764da72cf07cadcaaaf554474eae20116921d4
--- /dev/null
+++ b/doc/UI.md
@@ -0,0 +1,102 @@
+USER INTERFACE
+==============
+
+Button states
+-------------
+If the HTML Form has no modifications, the `Close`, `New` and `Delete`
+buttons are enabled. The `Save` button is disabled. 
+  
+If the HTML Form has modifications, the `Save`, `Close`, `New`, and
+`Delete` button is enabled. No button is disabled.
+
+
+Save Button 
+-----------
+
+* User presses the Save button
+  1. Reset all validation states
+  1. Client validates HTML Form
+  1. Form is submitted to server
+	 * Success: 
+		 1. Show message provided by server
+		 1. Current formelements and data will be reloaded.
+		 1. Process server reponse 'redirect':
+			* 'client': No redirect.
+			* 'no': No redirect.
+			* 'url': Redirect to URL
+	 * Failure: Happens on communication errors, if data validation
+       fails, form actions fails or saving data fails.
+	     1. Show error message.
+         1. Client: Ignore server reponse 'redirect'. Client stays on current page.
+    
+
+Close Button
+------------
+* User presses the Close button
+	1. Form not modified by user: Client redirects to previous page.
+	1. Form modified by user: Ask User 'You have unsaved changes. Do you want to close?'
+       * Yes: Client redirects to previous page.
+       * No: Client stays on current page.
+       * Save & Close: 
+		 1. Client reset all validation states
+		 1. Client validates HTML Form
+		 1. Client submits form to server.
+			* Success: Process server response 'redirect':
+			  * 'client': Client shows previous page.
+	          * 'no': No redirect.
+              * 'url': Redirect to URL
+		    * Failure: Happens on communication errors, if data validation
+	          fails, form actions fails or saving data fails.
+			  * Show error message. 
+			  * Client: No redirect. Ignore server reponse 'redirect'.
+
+Delete Button: Main record
+--------------------------
+* User presses the button. Ask User 'Do you really want to delete the record?
+  * Yes: 
+    * Delete record on server.
+    * Process server reponse 'redirect':
+      * 'client': Client redirects to previous page.
+      * 'no': Error message.
+      * 'url': Redirect to URL
+  * No:
+    * Client does not delete record on server.
+    * No redirect. Client stays on current page.
+
+New Button
+----------
+* User presses the button
+  * Form not modified by user: Client redirects to href url.
+  * Form modified by user: Ask User 'You have unsaved changes. Do you want to save first?'
+    * Yes:
+      * Client reset all validation states
+      * Client validates HTML Form
+      * Form is submitted to server
+        * Success:
+          * Client: Ignore server reponse 'redirect'. Client redirects to href url.
+        * Failure: Happens on communication errors, if data validation fails, form actions fails or saving data fails. 
+           * Show error message.
+           * Client: Ignore server reponse 'redirect'. Client stays on current page.
+    * No: 
+      * Client does not save the modified record.
+      * Client redirects to href url.
+    * Cancel:
+      * Client does not save the modified record.
+      * Client stays on current page.
+  
+
+File Handling: Upload
+---------------------
+* No previous uploaded file present
+  1. User presses the Browse button
+    1. User selects file
+      1. File is uploaded to qfq immediately
+      1. Browse button gets disabled and hidden
+      1. File delete button is shown
+    1. User cancels file selection
+      1. no action
+* Previous uploaded file present
+  1. User deletes file
+    1. File delete button gets disabled and hidden
+    1. Browse button gets enabled and displayed
+  
diff --git a/javascript/src/Element/Checkbox.js b/javascript/src/Element/Checkbox.js
index ebd8c23f3bc7989c169a09d26aeb7313c401985c..a191f693adfd56b8af46cb27f0339cd6358ac7f6 100644
--- a/javascript/src/Element/Checkbox.js
+++ b/javascript/src/Element/Checkbox.js
@@ -19,20 +19,38 @@ QfqNS.Element = QfqNS.Element || {};
     function Checkbox($element) {
         n.FormGroup.call(this, $element);
 
-        if (!this.isType("checkbox")) {
+        var type = "checkbox";
+
+        if (!this.isType(type)) {
             throw new Error("$element is not of type 'checkbox'");
         }
+
+        // We allow one Form Group to have several checkboxes. Therefore, we have to remember which checkbox was
+        // selected if possible.
+        if ($element.length === 1 && $element.attr('type') === type) {
+            this.$singleElement = $element;
+        } else {
+            this.$singleElement = null;
+        }
     }
 
     Checkbox.prototype = Object.create(n.FormGroup.prototype);
     Checkbox.prototype.constructor = Checkbox;
 
     Checkbox.prototype.setValue = function (val) {
-        this.$element.prop('checked', val);
+        if (this.$singleElement) {
+            this.$singleElement.prop('checked', val);
+        } else {
+            this.$element.prop('checked', val);
+        }
     };
 
     Checkbox.prototype.getValue = function () {
-        return this.$element.prop('checked');
+        if (this.$singleElement) {
+            return this.$singleElement.prop('checked');
+        } else {
+            return this.$element.prop('checked');
+        }
     };
 
     n.Checkbox = Checkbox;
diff --git a/mockup/elementconfiguration.html b/mockup/elementconfiguration.html
index bf357b1d45bfc7e3ee8034e6a3e661ea213369b0..dd517d4a05376484b35c154ef314036add095cf1 100644
--- a/mockup/elementconfiguration.html
+++ b/mockup/elementconfiguration.html
@@ -172,6 +172,38 @@
             </div>
         </div>
 
+        <div class="form-group">
+            <div class="col-md-2">
+                <b class="control-label">
+                    Checkbox 3 test
+                </b>
+            </div>
+
+
+            <div class="col-md-6">
+                <div class="checkbox">
+                    <label>
+                        <input name='checkbox3_1' type="checkbox" value="reminder_value">
+                    </label>
+
+                </div>
+                <div class="checkbox">
+                    <label>
+                        <input name='checkbox3_2' type="checkbox" value="reminder_value">
+                    </label>
+
+                </div>
+                <div class="checkbox">
+                    <label>
+                        <input name='checkbox3_3' type="checkbox" value="reminder_value">
+                    </label>
+
+                </div>
+            </div>
+            <div class="col-md-4">
+
+            </div>
+        </div>
     </form>
 </div>
 
diff --git a/tests/jasmine/acceptance/MIT.LICENSE b/tests/jasmine/acceptance/MIT.LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..aff8ed47a1a4b86c9ccec24d2a76b4d99a78a707
--- /dev/null
+++ b/tests/jasmine/acceptance/MIT.LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2008-2014 Pivotal Labs
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/tests/jasmine/acceptance/SpecRunner.html b/tests/jasmine/acceptance/SpecRunner.html
new file mode 100644
index 0000000000000000000000000000000000000000..c4c35829481ca29709674513c6edda49dae80b95
--- /dev/null
+++ b/tests/jasmine/acceptance/SpecRunner.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Jasmine Spec Runner v2.4.1</title>
+
+    <link rel="shortcut icon" type="image/png" href="../lib/jasmine-2.4.1/jasmine_favicon.png">
+    <link rel="stylesheet" href="../lib/jasmine-2.4.1/jasmine.css">
+
+    <script src="../lib/jasmine-2.4.1/jasmine.js"></script>
+    <script src="../lib/jasmine-2.4.1/jasmine-html.js"></script>
+    <script src="../lib/jasmine-2.4.1/boot.js"></script>
+
+    <script src="../helper/mock-ajax.js"></script>
+
+    <script src="../../../js/jquery.min.js"></script>
+    <script src="../../../js/bootstrap.min.js"></script>
+    <script src="../../../js/EventEmitter.min.js"></script>
+
+    <!-- include source files here... -->
+    <script src="../../../js/qfq.debug.js"></script>
+
+    <!-- include spec files here... -->
+    <script src="spec/FileUploadSpec.js"></script>
+
+</head>
+
+
+<body>
+
+<div class="col-md-2 ">
+    <div class="btn-toolbar pull-right" role="toolbar">
+        <div class="btn-group" role="group">
+            <button id="save-button" type="button" class="btn btn-default navbar-btn"><span
+                    class="glyphicon glyphicon-ok"></span></button>
+            <button id="close-button" type="button" class="btn btn-default navbar-btn"><span
+                    class="glyphicon glyphicon-remove"></span></button>
+        </div>
+        <div class="btn-group" role="group">
+            <button id="delete-button" type="button" class="btn btn-default navbar-btn"><span
+                    class="glyphicon glyphicon-trash"></span></button>
+        </div>
+        <div class="btn-group" role="group">
+            <a id="form-new-button" href="personmock.html?s=badcaffe1" class="btn btn-default navbar-btn"><span
+                    class="glyphicon glyphicon-plus"></span></a>
+        </div>
+    </div>
+</div>
+
+<form id="myForm" class="form-horizontal" data-toggle="validator">
+
+</form>
+
+<script type="text/template" id="fileupload_new">
+    <input type="hidden" name="s" value="badcaffee1234">
+
+    <div class="form-group">
+        <div class="col-md-2">
+            <label for="fileupload" class="control-label">File upload</label>
+        </div>
+        <div class="col-md-6">
+            <div class="col-md-6">
+                <div class="uploaded-file hidden"><span class="uploaded-file-name">john.doe.png</span>
+                    <button class="delete-file" data-sip="filedeletesip"
+                            name="trash-picture:1"><span
+                            class="glyphicon glyphicon-trash"></span></button>
+                </div>
+                <input id="fileupload" name="picture:1" class="hidden" type="file"
+                       data-sip="fileuploadsip">
+
+                <div class="help-block with-errors"></div>
+            </div>
+        </div>
+    </div>
+</script>
+
+</body>
+</html>
diff --git a/tests/jasmine/unit/SpecRunner.html b/tests/jasmine/unit/SpecRunner.html
index c1f40d8ccd47447230637da9f241529729cbc811..10450811dc000ee9378eb7c64c6a7591f109b9c5 100644
--- a/tests/jasmine/unit/SpecRunner.html
+++ b/tests/jasmine/unit/SpecRunner.html
@@ -316,6 +316,39 @@
             </div>
         </div>
 
+        <div class="form-group">
+            <div class="col-md-2">
+                <b class="control-label">
+                    Checkbox 3 test
+                </b>
+            </div>
+
+
+            <div class="col-md-6">
+                <div class="checkbox">
+                    <label>
+                        <input name='checkbox3_1' type="checkbox" value="reminder_value">
+                    </label>
+
+                </div>
+                <div class="checkbox">
+                    <label>
+                        <input name='checkbox3_2' type="checkbox" value="reminder_value">
+                    </label>
+
+                </div>
+                <div class="checkbox">
+                    <label>
+                        <input name='checkbox3_3' type="checkbox" value="reminder_value">
+                    </label>
+
+                </div>
+            </div>
+            <div class="col-md-4">
+
+            </div>
+        </div>
+
     </form>
 
 </section>
diff --git a/tests/jasmine/unit/SpecRunner.tmpl b/tests/jasmine/unit/SpecRunner.tmpl
index 1c5d61e78f05d9be8efcdd0628eb486389d512aa..3926797bc6b1287e0f84b89b2f4613572f2facdb 100644
--- a/tests/jasmine/unit/SpecRunner.tmpl
+++ b/tests/jasmine/unit/SpecRunner.tmpl
@@ -290,8 +290,40 @@
             </div>
         </div>
 
-    </form>
+        <div class="form-group">
+            <div class="col-md-2">
+                <b class="control-label">
+                    Checkbox 3 test
+                </b>
+            </div>
+
+
+            <div class="col-md-6">
+                <div class="checkbox">
+                    <label>
+                        <input name='checkbox3_1' type="checkbox" value="reminder_value">
+                    </label>
+
+                </div>
+                <div class="checkbox">
+                    <label>
+                        <input name='checkbox3_2' type="checkbox" value="reminder_value">
+                    </label>
+
+                </div>
+                <div class="checkbox">
+                    <label>
+                        <input name='checkbox3_3' type="checkbox" value="reminder_value">
+                    </label>
 
+                </div>
+            </div>
+            <div class="col-md-4">
+
+            </div>
+        </div>
+
+    </form>
 </section>
 <% with (scripts) { %>
 <% [].concat(polyfills, jasmine, boot, vendor, helpers, src, specs,reporters).forEach(function(script){ %>
diff --git a/tests/jasmine/unit/spec/ElementCheckboxSpec.js b/tests/jasmine/unit/spec/ElementCheckboxSpec.js
index 9bc9241c1978a9b2e57a78cd0927e61927041892..95b24217856315e0a31baa37687144166202eb19 100644
--- a/tests/jasmine/unit/spec/ElementCheckboxSpec.js
+++ b/tests/jasmine/unit/spec/ElementCheckboxSpec.js
@@ -47,4 +47,31 @@ describe("Element Checkbox", function () {
         expect($reminderCheckbox.prop('checked')).toBe(true);
         expect($checkbox2.prop('checked')).toBe(false);
     });
+
+    it('should properly handle several checkboxes in one Form Group', function () {
+        var $checkbox3_1 = $("[name='checkbox3_1']");
+        var $checkbox3_2 = $("[name='checkbox3_2']");
+        var $checkbox3_3 = $("[name='checkbox3_3']");
+
+        var checkbox3_1 = new QfqNS.Element.Checkbox($checkbox3_1);
+        checkbox3_1.setValue(true);
+
+        expect(checkbox3_1.getValue()).toBe(true);
+
+        expect($checkbox3_1.prop('checked')).toBe(true);
+        expect($checkbox3_2.prop('checked')).toBe(false);
+        expect($checkbox3_3.prop('checked')).toBe(false);
+
+        $('#myForm')[0].reset();
+
+        var checkbox3_2 = new QfqNS.Element.Checkbox($checkbox3_2);
+        checkbox3_2.setValue(true);
+
+        expect(checkbox3_2.getValue()).toBe(true);
+
+        expect($checkbox3_2.prop('checked')).toBe(true);
+        expect($checkbox3_1.prop('checked')).toBe(false);
+        expect($checkbox3_3.prop('checked')).toBe(false);
+
+    });
 });
\ No newline at end of file
diff --git a/tests/jasmine/unit/spec/ElementFormGroupSpec.js b/tests/jasmine/unit/spec/ElementFormGroupSpec.js
index 32d762307fb6a7123abcfa0b1bd2ff9a23cf09a3..fcfaf9a34ee10aa63977126dd4a6a743c598a898 100644
--- a/tests/jasmine/unit/spec/ElementFormGroupSpec.js
+++ b/tests/jasmine/unit/spec/ElementFormGroupSpec.js
@@ -97,7 +97,7 @@ describe("Element FormGroup", function () {
         expect(personGender.hasHelpBlock()).toBe(true);
     });
 
-    it("should properly disable the item", function () {
+    xit("should properly disable the item", function () {
         personGender.setEnabled(false);
     });
 });
\ No newline at end of file